Performance: Standardize lodash imports to use destructured members (#33040)

* Performance: Standardize lodash imports to use destructured members
Changes lodash imports of the form `import x from 'lodash/x'` to
`import { x } from 'lodash'` to reduce bundle size.

* Remove unnecessary _ import from Graph component

* Enforce lodash import style

* Fix remaining lodash imports
This commit is contained in:
kay delaney 2021-04-21 08:38:00 +01:00 committed by GitHub
parent 2bb7eb18d1
commit bad048b7ba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
299 changed files with 1135 additions and 1137 deletions

View File

@ -1,11 +1,12 @@
{
"extends": ["@grafana/eslint-config"],
"root": true,
"plugins": ["no-only-tests", "@emotion"],
"plugins": ["no-only-tests", "@emotion", "lodash"],
"rules": {
"no-only-tests/no-only-tests": "error",
"react/prop-types": "off",
"@emotion/jsx-import": "error"
"@emotion/jsx-import": "error",
"lodash/import-scope": [2, "member"]
},
"overrides": [
{

View File

@ -146,6 +146,7 @@
"eslint": "7.21.0",
"eslint-config-prettier": "7.2.0",
"eslint-plugin-jsdoc": "31.6.1",
"eslint-plugin-lodash": "^7.2.0",
"eslint-plugin-no-only-tests": "2.4.0",
"eslint-plugin-prettier": "3.3.1",
"eslint-plugin-react": "7.22.0",

View File

@ -1,7 +1,7 @@
import { Field, DataFrame, DataFrameDTO, FieldDTO, FieldType } from '../types/dataFrame';
import { QueryResultMeta } from '../types/data';
import { guessFieldTypeFromValue, guessFieldTypeForField, toDataFrameDTO } from './processDataFrame';
import isString from 'lodash/isString';
import { isString } from 'lodash';
import { makeFieldParser } from '../utils/fieldParser';
import { MutableVector, Vector } from '../types/vector';
import { ArrayVector } from '../vector/ArrayVector';

View File

@ -1,5 +1,5 @@
import sinon, { SinonFakeTimers } from 'sinon';
import each from 'lodash/each';
import { each } from 'lodash';
import * as dateMath from './datemath';
import { dateTime, DurationUnit, DateTime } from './moment_wrapper';

View File

@ -1,5 +1,4 @@
import includes from 'lodash/includes';
import isDate from 'lodash/isDate';
import { includes, isDate } from 'lodash';
import { DateTime, dateTime, dateTimeForTimeZone, ISO_8601, isDateTime, DurationUnit } from './moment_wrapper';
import { TimeZone } from '../types/index';

View File

@ -1,6 +1,4 @@
import each from 'lodash/each';
import groupBy from 'lodash/groupBy';
import has from 'lodash/has';
import { each, groupBy, has } from 'lodash';
import { RawTimeRange, TimeRange, TimeZone, IntervalValues } from '../types/time';

View File

@ -1,5 +1,5 @@
// Libraries
import _ from 'lodash';
import { toString, toNumber as _toNumber, isEmpty, isBoolean } from 'lodash';
// Types
import { Field, FieldType } from '../types/dataFrame';
@ -36,7 +36,7 @@ const timeFormats: KeyValue<boolean> = {
};
export function getDisplayProcessor(options?: DisplayProcessorOptions): DisplayProcessor {
if (!options || _.isEmpty(options) || !options.field) {
if (!options || isEmpty(options) || !options.field) {
return toStringProcessor;
}
@ -65,7 +65,7 @@ export function getDisplayProcessor(options?: DisplayProcessorOptions): DisplayP
value = dateTime(value).valueOf();
}
let text = _.toString(value);
let text = toString(value);
let numeric = isStringUnit ? NaN : toNumber(value);
let prefix: string | undefined = undefined;
let suffix: string | undefined = undefined;
@ -87,7 +87,7 @@ export function getDisplayProcessor(options?: DisplayProcessorOptions): DisplayP
}
if (!isNaN(numeric)) {
if (shouldFormat && !_.isBoolean(value)) {
if (shouldFormat && !isBoolean(value)) {
const v = formatFunc(numeric, config.decimals, null, options.timeZone);
text = v.text;
suffix = v.suffix;
@ -123,11 +123,11 @@ function toNumber(value: any): number {
if (typeof value === 'boolean') {
return value ? 1 : 0;
}
return _.toNumber(value);
return _toNumber(value);
}
function toStringProcessor(value: any): DisplayValue {
return { text: _.toString(value), numeric: toNumber(value) };
return { text: toString(value), numeric: toNumber(value) };
}
export function getRawDisplayProcessor(): DisplayProcessor {

View File

@ -1,7 +1,7 @@
import { Field, FieldType } from '../types/dataFrame';
import { Vector } from '../types/vector';
import { dateTime } from '../datetime';
import isNumber from 'lodash/isNumber';
import { isNumber } from 'lodash';
type IndexComparer = (a: number, b: number) => number;

View File

@ -1,4 +1,4 @@
import merge from 'lodash/merge';
import { merge } from 'lodash';
import { getFieldDisplayValues, GetFieldDisplayValuesOptions } from './fieldDisplay';
import { toDataFrame } from '../dataframe/processDataFrame';
import { ReducerID } from '../transformations/fieldReducer';

View File

@ -1,5 +1,4 @@
import toString from 'lodash/toString';
import isEmpty from 'lodash/isEmpty';
import { toString, isEmpty } from 'lodash';
import { getDisplayProcessor } from './displayProcessor';
import {

View File

@ -19,10 +19,7 @@ import {
} from '../types';
import { fieldMatchers, reduceField, ReducerID } from '../transformations';
import { FieldMatcher } from '../types/transformations';
import isNumber from 'lodash/isNumber';
import set from 'lodash/set';
import unset from 'lodash/unset';
import get from 'lodash/get';
import { isNumber, set, unset, get } from 'lodash';
import { getDisplayProcessor, getRawDisplayProcessor } from './displayProcessor';
import { guessFieldTypeForField } from '../dataframe';
import { standardFieldConfigEditorRegistry } from './standardFieldConfigEditorRegistry';

View File

@ -1,4 +1,4 @@
import toNumber from 'lodash/toNumber';
import { toNumber } from 'lodash';
import { DataFrame, DisplayValue, GrafanaTheme, TimeZone } from '../types';
import { getDisplayProcessor } from './displayProcessor';
import { formattedValueToString } from '../valueFormats';

View File

@ -11,7 +11,7 @@ import {
} from '../types';
import { FieldConfigEditorBuilder, PanelOptionsEditorBuilder } from '../utils/OptionsUIBuilders';
import { ComponentClass, ComponentType } from 'react';
import set from 'lodash/set';
import { set } from 'lodash';
import { deprecationWarning } from '../utils';
import { FieldConfigOptionsRegistry } from '../field';
import { createFieldConfigRegistry } from './registryFactories';

View File

@ -1,4 +1,4 @@
import difference from 'lodash/difference';
import { difference } from 'lodash';
import { fieldReducers, ReducerID, reduceField } from './fieldReducer';

View File

@ -1,5 +1,5 @@
// Libraries
import isNumber from 'lodash/isNumber';
import { isNumber } from 'lodash';
import { NullValueMode, Field, FieldState, FieldCalcs, FieldType } from '../types/index';
import { Registry, RegistryItem } from '../utils/Registry';

View File

@ -9,7 +9,7 @@ import { RowVector } from '../../vector/RowVector';
import { ArrayVector, BinaryOperationVector, ConstantVector } from '../../vector';
import { AsNumberVector } from '../../vector/AsNumberVector';
import { getTimeField } from '../../dataframe/processDataFrame';
import defaults from 'lodash/defaults';
import { defaults } from 'lodash';
import { BinaryOperationID, binaryOperators } from '../../utils/binaryOperators';
import { ensureColumnsTransformer } from './ensureColumns';
import { getFieldDisplayName } from '../../field';

View File

@ -1,6 +1,6 @@
// Libraries
import Papa, { ParseConfig, Parser, ParseResult } from 'papaparse';
import defaults from 'lodash/defaults';
import { defaults } from 'lodash';
// Types
import { DataFrame, Field, FieldConfig, FieldType } from '../types';

View File

@ -1,4 +1,4 @@
import flatten from 'lodash/flatten';
import { flatten } from 'lodash';
import tinycolor from 'tinycolor2';
import { GrafanaTheme, GrafanaThemeType } from '../types/theme';

View File

@ -2,7 +2,7 @@
* @preserve jquery-param (c) 2015 KNOWLEDGECODE | MIT
*/
import _ from 'lodash';
import { toNumber } from 'lodash';
import { ExploreUrlState } from '../types/explore';
/**
@ -156,7 +156,7 @@ export function parseKeyValue(keyValue: string) {
let parsedVal: any;
if (typeof val === 'string' && val !== '') {
parsedVal = val === 'true' || val === 'false' ? val === 'true' : _.toNumber(val);
parsedVal = val === 'true' || val === 'false' ? val === 'true' : toNumber(val);
} else {
parsedVal = val;
}

View File

@ -1,4 +1,4 @@
import merge from 'lodash/merge';
import { merge } from 'lodash';
import { getTheme } from '@grafana/ui';
import {
BuildInfo,

View File

@ -1,8 +1,6 @@
// @ts-ignore
import * as _ from 'lodash';
import { difference, sortBy } from 'lodash';
import { Task } from './task';
import GithubClient from '../utils/githubClient';
import difference from 'lodash/difference';
import chalk from 'chalk';
import { useSpinner } from '../utils/useSpinner';
@ -26,8 +24,8 @@ const getPackageChangelog = (packageName: string, issues: any[]) => {
}
let markdown = chalk.bold.yellow(`\n\n/*** ${packageName} changelog ***/\n\n`);
const bugs = _.sortBy(issues.filter(filterBugs), 'title');
const notBugs = _.sortBy(difference(issues, bugs), 'title');
const bugs = sortBy(issues.filter(filterBugs), 'title');
const notBugs = sortBy(difference(issues, bugs), 'title');
if (notBugs.length > 0) {
markdown += '### Features / Enhancements\n';
@ -89,7 +87,7 @@ const changelogTaskRunner = ({ milestone }: ChangelogOptions) =>
mergedIssues.push(item);
}
}
const issues = _.sortBy(mergedIssues, 'title');
const issues = sortBy(mergedIssues, 'title');
const toolkitIssues = issues.filter((item: any) =>
item.labels.find((label: any) => label.name === 'area/grafana/toolkit')

View File

@ -1,6 +1,6 @@
import { Task, TaskRunner } from './task';
import fs from 'fs';
import _ from 'lodash';
import { template as _template } from 'lodash';
import { prompt } from 'inquirer';
import { pascalCase } from '../utils/pascalCase';
import { promptConfirm, promptInput, promptList } from '../utils/prompt';
@ -53,7 +53,7 @@ export const promptDetails = () => {
export const generateComponents: ComponentGenerator = async ({ details, path }) => {
const name = pascalCase(details.name);
const getCompiled = (template: string) => {
return _.template(template)({ ...details, name });
return _template(template)({ ...details, name });
};
const filePath = `${path}/${name}`;
let paths = [];

View File

@ -2,7 +2,7 @@ import chalk from 'chalk';
import commandExists from 'command-exists';
import { promises as fs, readFileSync } from 'fs';
import { prompt } from 'inquirer';
import kebabCase from 'lodash/kebabCase';
import { kebabCase } from 'lodash';
import path from 'path';
import gitPromise from 'simple-git/promise';
import { promptConfirm, promptInput } from '../../utils/prompt';

View File

@ -1,3 +1,3 @@
import _ from 'lodash';
import { flow, camelCase, upperFirst } from 'lodash';
export const pascalCase = _.flow(_.camelCase, _.upperFirst);
export const pascalCase = flow(camelCase, upperFirst);

View File

@ -1,6 +1,6 @@
import React from 'react';
import tinycolor from 'tinycolor2';
import debounce from 'lodash/debounce';
import { debounce } from 'lodash';
import { ColorPickerProps } from './ColorPickerPopover';
import { Input } from '../Forms/Legacy/Input/Input';

View File

@ -1,5 +1,4 @@
import React, { Component, createRef } from 'react';
import omit from 'lodash/omit';
import { PopoverController } from '../Tooltip/PopoverController';
import { Popover } from '../Tooltip/Popover';
import { ColorPickerPopover, ColorPickerProps, ColorPickerChangeHandler } from './ColorPickerPopover';
@ -43,7 +42,7 @@ export const colorPickerFactory = <T extends ColorPickerProps>(
const { theme, children } = this.props;
const styles = getStyles(theme);
const popoverElement = React.createElement(popover, {
...omit(this.props, 'children'),
...{ ...this.props, children: null },
onChange: this.onColorChange,
});

View File

@ -2,7 +2,7 @@ import React from 'react';
import { mount, ReactWrapper } from 'enzyme';
import { ColorPickerPopover } from './ColorPickerPopover';
import { ColorSwatch } from './NamedColorsGroup';
import flatten from 'lodash/flatten';
import { flatten } from 'lodash';
import { getNamedColorPalette, getColorFromHexRgbOrName } from '@grafana/data';
const allColors = flatten(Array.from(getNamedColorPalette().values()));

View File

@ -2,8 +2,7 @@ import React, { FunctionComponent } from 'react';
import { Themeable } from '../../types';
import { ColorDefinition } from '@grafana/data';
import { Color } from 'csstype';
import upperFirst from 'lodash/upperFirst';
import find from 'lodash/find';
import { upperFirst, find } from 'lodash';
type ColorChangeHandler = (color: ColorDefinition) => void;

View File

@ -1,5 +1,5 @@
import React, { FC, useCallback, useEffect, useRef } from 'react';
import isNil from 'lodash/isNil';
import { isNil } from 'lodash';
import classNames from 'classnames';
import { css } from '@emotion/css';
import Scrollbars from 'react-custom-scrollbars';

View File

@ -1,7 +1,7 @@
import { ThemeContext } from '../../index';
import { GrafanaTheme, VariableSuggestion } from '@grafana/data';
import { css, cx } from '@emotion/css';
import _ from 'lodash';
import { groupBy, capitalize } from 'lodash';
import React, { useRef, useContext, useMemo } from 'react';
import useClickAway from 'react-use/lib/useClickAway';
import { List } from '../index';
@ -70,7 +70,7 @@ export const DataLinkSuggestions: React.FC<DataLinkSuggestionsProps> = ({ sugges
});
const groupedSuggestions = useMemo(() => {
return _.groupBy(suggestions, (s) => s.origin);
return groupBy(suggestions, (s) => s.origin);
}, [suggestions]);
const styles = getStyles(theme);
@ -91,7 +91,7 @@ export const DataLinkSuggestions: React.FC<DataLinkSuggestionsProps> = ({ sugges
<DataLinkSuggestionsList
{...otherProps}
suggestions={groupedSuggestions[key]}
label={`${_.capitalize(key)}`}
label={`${capitalize(key)}`}
activeIndex={otherProps.activeIndex}
activeIndexOffset={indexOffset}
key={key}

View File

@ -2,7 +2,7 @@ import { DataFrame, DataLink, GrafanaTheme, VariableSuggestion } from '@grafana/
import React, { useState } from 'react';
import { css } from '@emotion/css';
import { Button } from '../../Button/Button';
import cloneDeep from 'lodash/cloneDeep';
import { cloneDeep } from 'lodash';
import { Modal } from '../../Modal/Modal';
import { stylesFactory, useTheme } from '../../../themes';
import { DataLinksListItem } from './DataLinksListItem';

View File

@ -1,6 +1,6 @@
import React, { PureComponent } from 'react';
import { css } from '@emotion/css';
import uniqueId from 'lodash/uniqueId';
import { uniqueId } from 'lodash';
import { DataSourceSettings } from '@grafana/data';
import { Button } from '../Button';
import { FormField } from '../FormField/FormField';

View File

@ -1,5 +1,5 @@
import React, { PureComponent } from 'react';
import uniqueId from 'lodash/uniqueId';
import { uniqueId } from 'lodash';
import { Placement } from '@popperjs/core';
import { Tooltip } from '../../../Tooltip/Tooltip';
import { Icon } from '../../..';

View File

@ -1,6 +1,6 @@
import React, { useCallback, useRef } from 'react';
import { css, cx } from '@emotion/css';
import uniqueId from 'lodash/uniqueId';
import { uniqueId } from 'lodash';
import { GrafanaTheme, SelectableValue } from '@grafana/data';
import { RadioButtonSize, RadioButton } from './RadioButton';
import { Icon } from '../../Icon/Icon';

View File

@ -1,10 +1,9 @@
// Libraries
import $ from 'jquery';
import React, { PureComponent } from 'react';
import uniqBy from 'lodash/uniqBy';
import { uniqBy } from 'lodash';
// Types
import { TimeRange, GraphSeriesXY, TimeZone, createDimension } from '@grafana/data';
import _ from 'lodash';
import { FlotPosition, FlotItem } from './types';
import { VizTooltipProps, VizTooltipContentProps, ActiveDimensions, VizTooltip } from '../VizTooltip';
import { GraphTooltip } from './GraphTooltip/GraphTooltip';

View File

@ -1,7 +1,6 @@
import React from 'react';
import { GraphSeriesXY } from '@grafana/data';
import difference from 'lodash/difference';
import isEqual from 'lodash/isEqual';
import { difference, isEqual } from 'lodash';
export interface GraphSeriesTogglerAPI {
onSeriesToggle: (label: string, event: React.MouseEvent<HTMLElement>) => void;

View File

@ -1,5 +1,5 @@
import React from 'react';
import isNumber from 'lodash/isNumber';
import { isNumber } from 'lodash';
import { GraphNGLegendEventMode, XYFieldMatchers } from './types';
import {
ArrayVector,

View File

@ -3,7 +3,7 @@
import { isObject, getObjectName, getType, getValuePreview, cssClass, createElement } from './helpers';
import _ from 'lodash';
import { isNumber } from 'lodash';
const DATE_STRING_REGEX = /(^\d{1,4}[\.|\\/|-]\d{1,2}[\.|\\/|-]\d{1,4})(\s*(?:0?[1-9]:[0-5]|1(?=[012])\d:[0-5])\d\s*[ap]m)?$/;
const PARTIAL_DATE_REGEX = /\d{2}:\d{2}:\d{2} GMT-\d{4}/;
@ -222,7 +222,7 @@ export class JsonExplorer {
}
isNumberArray() {
return this.json.length > 0 && this.json.length < 4 && (_.isNumber(this.json[0]) || _.isNumber(this.json[1]));
return this.json.length > 0 && this.json.length < 4 && (isNumber(this.json[0]) || isNumber(this.json[1]));
}
renderArray() {

View File

@ -1,5 +1,5 @@
import React, { PureComponent } from 'react';
import _ from 'lodash';
import { isEqual } from 'lodash';
import tinycolor from 'tinycolor2';
import { css, cx } from '@emotion/css';
import { LogRowModel, findHighlightChunksInText, GrafanaTheme } from '@grafana/data';
@ -76,7 +76,7 @@ class UnThemedLogRowMessage extends PureComponent<Props> {
const style = getLogRowStyles(theme, row.logLevel);
const { entry, hasAnsi, raw } = row;
const previewHighlights = highlighterExpressions?.length && !_.isEqual(highlighterExpressions, row.searchWords);
const previewHighlights = highlighterExpressions?.length && !isEqual(highlighterExpressions, row.searchWords);
const highlights = previewHighlights ? highlighterExpressions : row.searchWords;
const needsHighlighter =
highlights && highlights.length > 0 && highlights[0] && highlights[0].length > 0 && entry.length < MAX_CHARACTERS;

View File

@ -1,4 +1,4 @@
import _ from 'lodash';
import { debounce } from 'lodash';
import React, { Context } from 'react';
import { Value, Editor as CoreEditor } from 'slate';
@ -64,7 +64,7 @@ export class QueryField extends React.PureComponent<QueryFieldProps, QueryFieldS
constructor(props: QueryFieldProps, context: Context<any>) {
super(props, context);
this.runOnChangeDebounced = _.debounce(this.runOnChange, 500);
this.runOnChangeDebounced = debounce(this.runOnChange, 500);
const { onTypeahead, cleanText, portalOrigin, onWillApplySuggestion } = props;

View File

@ -1,4 +1,4 @@
import omit from 'lodash/omit';
import { omit } from 'lodash';
import React, { InputHTMLAttributes, FunctionComponent } from 'react';
import { FormField } from '../FormField/FormField';
import { Button } from '../Button/Button';

View File

@ -1,6 +1,6 @@
import React, { HTMLProps } from 'react';
import { cx } from '@emotion/css';
import _ from 'lodash';
import { isObject } from 'lodash';
import { SelectableValue } from '@grafana/data';
import { SegmentSelect, useExpandableLabel, SegmentProps } from './';
import { getSegmentStyles } from './styles';
@ -28,7 +28,7 @@ export function Segment<T>({
const styles = useStyles(getSegmentStyles);
if (!expanded) {
const label = _.isObject(value) ? value.label : value;
const label = isObject(value) ? value.label : value;
return (
<Label
@ -56,7 +56,7 @@ export function Segment<T>({
return (
<SegmentSelect
{...rest}
value={value && !_.isObject(value) ? { value } : value}
value={value && !isObject(value) ? { value } : value}
options={options}
width={width}
onClickOutside={() => setExpanded(false)}

View File

@ -1,6 +1,6 @@
import React, { HTMLProps } from 'react';
import { cx } from '@emotion/css';
import _ from 'lodash';
import { isObject } from 'lodash';
import { SegmentSelect } from './SegmentSelect';
import { SelectableValue } from '@grafana/data';
import { useExpandableLabel, SegmentProps } from '.';
@ -34,7 +34,7 @@ export function SegmentAsync<T>({
const styles = useStyles(getSegmentStyles);
if (!expanded) {
const label = _.isObject(value) ? value.label : value;
const label = isObject(value) ? value.label : value;
return (
<Label
@ -63,7 +63,7 @@ export function SegmentAsync<T>({
return (
<SegmentSelect
{...rest}
value={value && !_.isObject(value) ? { value } : value}
value={value && !isObject(value) ? { value } : value}
options={state.value ?? []}
width={width}
noOptionsMessage={noOptionMessageHandler(state)}

View File

@ -4,7 +4,7 @@ import { SelectableValue } from '@grafana/data';
import { Icon, Select, AsyncSelect, MultiSelect, AsyncMultiSelect } from '@grafana/ui';
import { getAvailableIcons, IconName } from '../../types';
import { select, boolean, number } from '@storybook/addon-knobs';
import kebabCase from 'lodash/kebabCase';
import { kebabCase } from 'lodash';
import { generateOptions } from './mockOptions';
import mdx from './Select.mdx';

View File

@ -1,7 +1,7 @@
import { PureComponent } from 'react';
import { interval, Subscription, Subject, of, NEVER } from 'rxjs';
import { tap, switchMap } from 'rxjs/operators';
import _ from 'lodash';
import { isEqual } from 'lodash';
import { stringToMs, SelectableValue } from '@grafana/data';
import { RefreshPicker } from '../RefreshPicker/RefreshPicker';
@ -63,7 +63,7 @@ export class SetInterval extends PureComponent<Props> {
componentDidUpdate(prevProps: Props) {
if (
(RefreshPicker.isLive(prevProps.interval) && RefreshPicker.isLive(this.props.interval)) ||
_.isEqual(prevProps, this.props)
isEqual(prevProps, this.props)
) {
return;
}

View File

@ -1,5 +1,4 @@
import cloneDeep from 'lodash/cloneDeep';
import omit from 'lodash/omit';
import { cloneDeep, omit } from 'lodash';
import {
fieldReducers,

View File

@ -1,6 +1,6 @@
import React, { PureComponent } from 'react';
import difference from 'lodash/difference';
import { difference } from 'lodash';
import { Select } from '../Select/Select';

View File

@ -1,6 +1,6 @@
import React, { HTMLProps, useRef } from 'react';
import { css, cx } from '@emotion/css';
import uniqueId from 'lodash/uniqueId';
import { uniqueId } from 'lodash';
import { GrafanaTheme, deprecationWarning } from '@grafana/data';
import { stylesFactory, useTheme } from '../../themes';
import { focusCss, getMouseFocusStyles } from '../../themes/mixins';

View File

@ -1,5 +1,5 @@
import React from 'react';
import debounce from 'lodash/debounce';
import { debounce } from 'lodash';
import { css } from '@emotion/css';
import { GrafanaTheme, DataFrame, CSVConfig, readCSV } from '@grafana/data';
import { Icon } from '../Icon/Icon';

View File

@ -7,7 +7,7 @@ import { TimeZoneDescription } from '../TimeZonePicker/TimeZoneDescription';
import { TimeZoneOffset } from '../TimeZonePicker/TimeZoneOffset';
import { Button } from '../../Button';
import { TimeZonePicker } from '../TimeZonePicker';
import isString from 'lodash/isString';
import { isString } from 'lodash';
import { selectors } from '@grafana/e2e-selectors';
interface Props {

View File

@ -2,7 +2,7 @@ import React, { PropsWithChildren } from 'react';
import { css, cx } from '@emotion/css';
import { GrafanaTheme, TimeZone, dateTimeFormat } from '@grafana/data';
import { useTheme, stylesFactory } from '../../../themes';
import isString from 'lodash/isString';
import { isString } from 'lodash';
interface Props {
timestamp: number;

View File

@ -7,7 +7,7 @@ import { Icon } from '../../Icon/Icon';
import { TimeZoneOffset } from './TimeZoneOffset';
import { TimeZoneDescription } from './TimeZoneDescription';
import { TimeZoneTitle } from './TimeZoneTitle';
import isString from 'lodash/isString';
import { isString } from 'lodash';
interface Props {
isFocused: boolean;

View File

@ -1,6 +1,6 @@
import React, { createRef } from 'react';
import ReactDOM from 'react-dom';
import _ from 'lodash';
import { isEqual } from 'lodash';
import { FixedSizeList } from 'react-window';
import { TypeaheadInfo } from './TypeaheadInfo';
@ -83,7 +83,7 @@ export class Typeahead extends React.PureComponent<Props, State> {
this.listRef.current.scrollToItem(this.state.typeaheadIndex);
}
if (_.isEqual(prevProps.groupedItems, this.props.groupedItems) === false) {
if (isEqual(prevProps.groupedItems, this.props.groupedItems) === false) {
const allItems = flattenGroupItems(this.props.groupedItems);
const longestLabel = calculateLongestLabel(allItems);
const { listWidth, listHeight, itemHeight } = calculateListSizes(this.context, allItems, longestLabel);

View File

@ -2,7 +2,7 @@ import React from 'react';
import { InlineList } from '../List/InlineList';
import { css } from '@emotion/css';
import { DisplayValue, formattedValueToString } from '@grafana/data';
import capitalize from 'lodash/capitalize';
import { capitalize } from 'lodash';
import { useStyles } from '../../themes/ThemeContext';
/**

View File

@ -3,8 +3,7 @@ import { css, cx } from '@emotion/css';
import { VizLegendTableProps } from './types';
import { Icon } from '../Icon/Icon';
import { useStyles } from '../../themes/ThemeContext';
import union from 'lodash/union';
import sortBy from 'lodash/sortBy';
import { union, sortBy } from 'lodash';
import { LegendTableItem } from './VizLegendTableItem';
import { GrafanaTheme } from '@grafana/data';

View File

@ -4,6 +4,12 @@ import { SuggestionsPlugin } from './suggestions';
import { Plugin as SlatePlugin } from '@grafana/slate-react';
import { SearchFunctionType } from '../utils';
import { CompletionItemGroup, SuggestionsState } from '../types';
// eslint-disable-next-line lodash/import-scope
import _ from 'lodash';
jest.spyOn(_, 'debounce').mockImplementation((func: (...args: any) => any) => {
return Object.assign(func, { cancel: jest.fn(), flush: jest.fn() });
});
jest.mock('../utils/searchFunctions', () => ({
// @ts-ignore
@ -26,10 +32,6 @@ jest.mock('../components/Typeahead/Typeahead', () => {
};
});
jest.mock('lodash/debounce', () => {
return (func: () => any) => func;
});
describe('SuggestionsPlugin', () => {
let plugin: SlatePlugin, nextMock: any, suggestions: CompletionItemGroup[], editorMock: any, eventMock: any;

View File

@ -1,6 +1,5 @@
import React from 'react';
import debounce from 'lodash/debounce';
import sortBy from 'lodash/sortBy';
import { debounce, sortBy } from 'lodash';
import { Editor as CoreEditor } from 'slate';
import { Plugin as SlatePlugin } from '@grafana/slate-react';

View File

@ -1,8 +1,4 @@
import map from 'lodash/map';
import sortBy from 'lodash/sortBy';
import flattenDeep from 'lodash/flattenDeep';
import chunk from 'lodash/chunk';
import zip from 'lodash/zip';
import { map, sortBy, flattenDeep, chunk, zip } from 'lodash';
import tinycolor from 'tinycolor2';
import lightTheme from '../themes/light';
import darkTheme from '../themes/dark';

View File

@ -1,4 +1,4 @@
import throttle from 'lodash/throttle';
import { throttle } from 'lodash';
/**
* @internal

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import _range from 'lodash/range';
import { range as _range } from 'lodash';
import renderIntoCanvas, {
BG_COLOR,

View File

@ -13,9 +13,7 @@
// limitations under the License.
import * as React from 'react';
import _get from 'lodash/get';
import _maxBy from 'lodash/maxBy';
import _values from 'lodash/values';
import { get as _get, maxBy as _maxBy, values as _values } from 'lodash';
import MdKeyboardArrowRight from 'react-icons/lib/md/keyboard-arrow-right';
import { css } from '@emotion/css';
import cx from 'classnames';

View File

@ -14,7 +14,7 @@
import cx from 'classnames';
import { css } from '@emotion/css';
import _groupBy from 'lodash/groupBy';
import { groupBy as _groupBy } from 'lodash';
import React from 'react';
import { compose, onlyUpdateForKeys, withProps, withState } from 'recompose';
import { autoColor, createStyle, Theme } from '../Theme';

View File

@ -13,7 +13,7 @@
// limitations under the License.
import * as React from 'react';
import _sortBy from 'lodash/sortBy';
import { sortBy as _sortBy } from 'lodash';
import IoIosArrowDown from 'react-icons/lib/io/ios-arrow-down';
import IoIosArrowRight from 'react-icons/lib/io/ios-arrow-right';
import { css } from '@emotion/css';

View File

@ -13,7 +13,7 @@
// limitations under the License.
import React from 'react';
import _get from 'lodash/get';
import { get as _get } from 'lodash';
import IoChevronRight from 'react-icons/lib/io/chevron-right';
import IoIosArrowDown from 'react-icons/lib/io/ios-arrow-down';
import { css } from '@emotion/css';

View File

@ -14,12 +14,15 @@
import * as React from 'react';
import { shallow } from 'enzyme';
import debounceMock from 'lodash/debounce';
// eslint-disable-next-line lodash/import-scope
import _ from 'lodash';
import UiFindInput from './UiFindInput';
import { UIInput } from '../uiElementsContext';
jest.mock('lodash/debounce');
const debounceMock = jest.spyOn(_, 'debounce').mockImplementation((func) => {
return Object.assign(func, { cancel: jest.fn(), flush: jest.fn() });
});
describe('UiFindInput', () => {
const flushMock = jest.fn();

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import _uniq from 'lodash/uniq';
import { uniq as _uniq } from 'lodash';
import memoize from 'lru-memoize';
import { getConfigValue } from '../utils/config/get-config';
import { getParent } from './span';

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import _isEqual from 'lodash/isEqual';
import { isEqual as _isEqual } from 'lodash';
// @ts-ignore
import { getTraceSpanIdsAsTree } from '../selectors/trace';

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import _values from 'lodash/values';
import { values as _values } from 'lodash';
import { followsFromRef } from './trace.fixture';
import {

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import _get from 'lodash/get';
import { get as _get } from 'lodash';
import EUpdateTypes from './EUpdateTypes';
import { DraggableBounds, DraggingUpdate } from './types';

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import _get from 'lodash/get';
import { get as _get } from 'lodash';
import defaultConfig from '../../constants/default-config';

View File

@ -13,7 +13,7 @@
// limitations under the License.
import moment from 'moment-timezone';
import _round from 'lodash/round';
import { round as _round } from 'lodash';
import { toFloatPrecision } from './number';

View File

@ -12,8 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import _find from 'lodash/find';
import _get from 'lodash/get';
import { find as _find, get as _get } from 'lodash';
import { TNil } from '../types';
import { TraceSpan } from '../types/trace';

View File

@ -8,6 +8,7 @@ import 'file-saver';
import 'jquery';
import '@grafana/ui/src/components/Icon/iconBundle';
// eslint-disable-next-line lodash/import-scope
import _ from 'lodash';
import ReactDOM from 'react-dom';
import React from 'react';

View File

@ -1,5 +1,5 @@
import React, { useMemo, useCallback, FC } from 'react';
import _ from 'lodash';
import { flatten } from 'lodash';
import { LegacyForms } from '@grafana/ui';
import { SelectableValue } from '@grafana/data';
@ -60,7 +60,7 @@ const useSelectOptions = ({ variables = [], options }: Props): Array<SelectableV
const useSelectedOption = (options: Array<SelectableValue<string>>, value: string): SelectableValue<string> => {
return useMemo(() => {
const allOptions = options.every((o) => o.options) ? _.flatten(options.map((o) => o.options)) : options;
const allOptions = options.every((o) => o.options) ? flatten(options.map((o) => o.options)) : options;
return allOptions.find((option) => option.value === value);
}, [options, value]);
};

View File

@ -1,5 +1,5 @@
import React, { Component } from 'react';
import _, { debounce } from 'lodash';
import { debounce, isNil } from 'lodash';
import { AsyncSelect } from '@grafana/ui';
import { getBackendSrv } from '@grafana/runtime';
@ -36,7 +36,7 @@ export class TeamPicker extends Component<Props, State> {
search(query?: string) {
this.setState({ isLoading: true });
if (_.isNil(query)) {
if (isNil(query)) {
query = '';
}

View File

@ -1,6 +1,6 @@
// Libraries
import React, { Component } from 'react';
import _, { debounce } from 'lodash';
import { debounce, isNil } from 'lodash';
// Components
import { AsyncSelect } from '@grafana/ui';
@ -37,7 +37,7 @@ export class UserPicker extends Component<Props, State> {
search(query?: string) {
this.setState({ isLoading: true });
if (_.isNil(query)) {
if (isNil(query)) {
query = '';
}

View File

@ -24,7 +24,7 @@ import {
ReduceOptions,
} from '@grafana/data/src/transformations/transformers/calculateField';
import defaults from 'lodash/defaults';
import { defaults } from 'lodash';
interface CalculateFieldTransformerEditorProps extends TransformerUIProps<CalculateFieldTransformerOptions> {}

View File

@ -13,7 +13,7 @@ import {
valueMatchers,
} from '@grafana/data';
import { Button, RadioButtonGroup, stylesFactory } from '@grafana/ui';
import cloneDeep from 'lodash/cloneDeep';
import { cloneDeep } from 'lodash';
import {
FilterByValueFilter,
FilterByValueMatch,

View File

@ -1,4 +1,4 @@
import _ from 'lodash';
import { debounce, find, indexOf, map, isObject, escape, unescape } from 'lodash';
import coreModule from '../../core_module';
import { ISCEService } from 'angular';
import { promiseToDigest } from 'app/core/utils/promiseToDigest';
@ -81,7 +81,7 @@ export class FormDropdownCtrl {
};
if (this.debounce) {
typeahead.lookup = _.debounce(typeahead.lookup, 500, { leading: true });
typeahead.lookup = debounce(typeahead.lookup, 500, { leading: true });
}
this.linkElement.keydown((evt) => {
@ -115,13 +115,13 @@ export class FormDropdownCtrl {
}
modelChanged() {
if (_.isObject(this.model)) {
if (isObject(this.model)) {
this.updateDisplay((this.model as any).text);
} else {
// if we have text use it
if (this.lookupText) {
this.getOptionsInternal('').then((options: any) => {
const item: any = _.find(options, { value: this.model });
const item: any = find(options, { value: this.model });
this.updateDisplay(item ? item.text : this.model);
});
} else {
@ -135,13 +135,13 @@ export class FormDropdownCtrl {
this.optionCache = options;
// extract texts
const optionTexts = _.map(options, (op: any) => {
return _.escape(op.text);
const optionTexts = map(options, (op: any) => {
return escape(op.text);
});
// add custom values
if (this.allowCustom && this.text !== '') {
if (_.indexOf(optionTexts, this.text) === -1) {
if (indexOf(optionTexts, this.text) === -1) {
optionTexts.unshift(this.text);
}
}
@ -182,24 +182,24 @@ export class FormDropdownCtrl {
}
updateValue(text: string) {
text = _.unescape(text);
text = unescape(text);
if (text === '' || this.text === text) {
return;
}
this.$scope.$apply(() => {
const option: any = _.find(this.optionCache, { text: text });
const option: any = find(this.optionCache, { text: text });
if (option) {
if (_.isObject(this.model)) {
if (isObject(this.model)) {
this.model = option;
} else {
this.model = option.value;
}
this.text = option.text;
} else if (this.allowCustom) {
if (_.isObject(this.model)) {
if (isObject(this.model)) {
(this.model as any).text = (this.model as any).value = text;
} else {
this.model = text;

View File

@ -1,4 +1,4 @@
import _ from 'lodash';
import { each } from 'lodash';
import coreModule from 'app/core/core_module';
// @ts-ignore
import Drop from 'tether-drop';
@ -28,7 +28,7 @@ export function infoPopover() {
const content = document.createElement('div');
content.className = 'markdown-html';
_.each(clone, (node) => {
each(clone, (node) => {
content.appendChild(node);
});

View File

@ -1,4 +1,4 @@
import _ from 'lodash';
import { clone, each, map } from 'lodash';
export class QueryPartDef {
type: string;
@ -31,7 +31,7 @@ export class QueryPart {
throw { message: 'Could not find query part ' + part.type };
}
part.params = part.params || _.clone(this.def.defaultParams);
part.params = part.params || clone(this.def.defaultParams);
this.params = part.params;
this.text = '';
this.updateText();
@ -53,7 +53,7 @@ export class QueryPart {
// handle optional parameters
// if string contains ',' and next param is optional, split and update both
if (this.hasMultipleParamsInString(strValue, index)) {
_.each(strValue.split(','), (partVal, idx) => {
each(strValue.split(','), (partVal, idx) => {
this.updateParam(partVal.trim(), idx);
});
return;
@ -84,7 +84,7 @@ export class QueryPart {
export function functionRenderer(part: any, innerExpr: string) {
const str = part.def.type + '(';
const parameters = _.map(part.params, (value, index) => {
const parameters = map(part.params, (value, index) => {
const paramType = part.def.params[index];
if (paramType.type === 'time') {
if (value === 'auto') {

View File

@ -1,4 +1,4 @@
import _ from 'lodash';
import { debounce, each, map, partial, escape, unescape } from 'lodash';
import $ from 'jquery';
import coreModule from 'app/core/core_module';
import { promiseToDigest } from '../../utils/promiseToDigest';
@ -90,7 +90,7 @@ export function queryPartEditorDirective(templateSrv: any) {
if (param.options) {
let options = param.options;
if (param.type === 'int') {
options = _.map(options, (val) => {
options = map(options, (val) => {
return val.toString();
});
}
@ -99,8 +99,8 @@ export function queryPartEditorDirective(templateSrv: any) {
$scope.$apply(() => {
$scope.handleEvent({ $event: { name: 'get-param-options' } }).then((result: any) => {
const dynamicOptions = _.map(result, (op) => {
return _.escape(op.value);
const dynamicOptions = map(result, (op) => {
return escape(op.value);
});
callback(dynamicOptions);
});
@ -114,7 +114,7 @@ export function queryPartEditorDirective(templateSrv: any) {
minLength: 0,
items: 1000,
updater: (value: string) => {
value = _.unescape(value);
value = unescape(value);
setTimeout(() => {
inputBlur.call($input[0], paramIndex);
}, 0);
@ -130,7 +130,7 @@ export function queryPartEditorDirective(templateSrv: any) {
};
if (debounceLookup) {
typeahead.lookup = _.debounce(typeahead.lookup, 500, { leading: true });
typeahead.lookup = debounce(typeahead.lookup, 500, { leading: true });
}
}
@ -147,7 +147,7 @@ export function queryPartEditorDirective(templateSrv: any) {
};
function addElementsAndCompile() {
_.each(partDef.params, (param: any, index: number) => {
each(partDef.params, (param: any, index: number) => {
if (param.optional && part.params.length <= index) {
return;
}
@ -163,10 +163,10 @@ export function queryPartEditorDirective(templateSrv: any) {
$paramLink.appendTo($paramsContainer);
$input.appendTo($paramsContainer);
$input.blur(_.partial(inputBlur, index));
$input.blur(partial(inputBlur, index));
$input.keyup(inputKeyDown);
$input.keypress(_.partial(inputKeyPress, index));
$paramLink.click(_.partial(clickFuncParam, index));
$input.keypress(partial(inputKeyPress, index));
$paramLink.click(partial(clickFuncParam, index));
addTypeahead($input, param, index);
});

View File

@ -1,5 +1,5 @@
import React from 'react';
import _ from 'lodash';
import { cloneDeep, find } from 'lodash';
import { SignIn } from './SignIn';
import BottomNavLinks from './BottomNavLinks';
import { contextSrv } from 'app/core/services/context_srv';
@ -7,13 +7,13 @@ import config from '../../config';
import { NavModelItem } from '@grafana/data';
export default function BottomSection() {
const navTree: NavModelItem[] = _.cloneDeep(config.bootData.navTree);
const navTree: NavModelItem[] = cloneDeep(config.bootData.navTree);
const bottomNav: NavModelItem[] = navTree.filter((item) => item.hideFromMenu);
const isSignedIn = contextSrv.isSignedIn;
const user = contextSrv.user;
if (user && user.orgCount > 1) {
const profileNode: any = _.find(bottomNav, { id: 'profile' });
const profileNode: any = find(bottomNav, { id: 'profile' });
if (profileNode) {
profileNode.showOrgSwitcher = true;
}

View File

@ -1,5 +1,5 @@
import React, { FC } from 'react';
import _ from 'lodash';
import { filter } from 'lodash';
import DropDownChild from './DropDownChild';
import { NavModelItem } from '@grafana/data';
import { Link } from '@grafana/ui';
@ -13,7 +13,7 @@ const SideMenuDropDown: FC<Props> = (props) => {
const { link, onHeaderClick } = props;
let childrenLinks: NavModelItem[] = [];
if (link.children) {
childrenLinks = _.filter(link.children, (item) => !item.hideFromMenu);
childrenLinks = filter(link.children, (item) => !item.hideFromMenu);
}
const linkContent = <span className="sidemenu-item-text">{link.text}</span>;

View File

@ -1,12 +1,12 @@
import React, { FC } from 'react';
import _ from 'lodash';
import { cloneDeep, filter } from 'lodash';
import TopSectionItem from './TopSectionItem';
import config from '../../config';
import { locationService } from '@grafana/runtime';
const TopSection: FC<any> = () => {
const navTree = _.cloneDeep(config.bootData.navTree);
const mainLinks = _.filter(navTree, (item) => !item.hideFromMenu);
const navTree = cloneDeep(config.bootData.navTree);
const mainLinks = filter(navTree, (item) => !item.hideFromMenu);
const searchLink = {
text: 'Search',
icon: 'search',

View File

@ -1,4 +1,4 @@
import _ from 'lodash';
import { clone } from 'lodash';
export class SqlPartDef {
type: string;
@ -57,7 +57,7 @@ export class SqlPart {
this.label = def.label;
}
part.params = part.params || _.clone(this.def.defaultParams);
part.params = part.params || clone(this.def.defaultParams);
this.params = part.params;
}

View File

@ -1,4 +1,4 @@
import _ from 'lodash';
import { debounce, each, indexOf, map, partial, escape, unescape } from 'lodash';
import $ from 'jquery';
import coreModule from 'app/core/core_module';
@ -95,7 +95,7 @@ export function sqlPartEditorDirective(templateSrv: any) {
if (param.options) {
let options = param.options;
if (param.type === 'int') {
options = _.map(options, (val) => {
options = map(options, (val) => {
return val.toString();
});
}
@ -104,13 +104,13 @@ export function sqlPartEditorDirective(templateSrv: any) {
$scope.$apply(() => {
$scope.handleEvent({ $event: { name: 'get-param-options', param: param } }).then((result: any) => {
const dynamicOptions = _.map(result, (op) => {
return _.escape(op.value);
const dynamicOptions = map(result, (op) => {
return escape(op.value);
});
// add current value to dropdown if it's not in dynamicOptions
if (_.indexOf(dynamicOptions, part.params[paramIndex]) === -1) {
dynamicOptions.unshift(_.escape(part.params[paramIndex]));
if (indexOf(dynamicOptions, part.params[paramIndex]) === -1) {
dynamicOptions.unshift(escape(part.params[paramIndex]));
}
callback(dynamicOptions);
@ -125,7 +125,7 @@ export function sqlPartEditorDirective(templateSrv: any) {
minLength: 0,
items: 1000,
updater: (value: string) => {
value = _.unescape(value);
value = unescape(value);
if (value === part.params[paramIndex]) {
clearTimeout(cancelBlur);
$input.focus();
@ -143,7 +143,7 @@ export function sqlPartEditorDirective(templateSrv: any) {
};
if (debounceLookup) {
typeahead.lookup = _.debounce(typeahead.lookup, 500, { leading: true });
typeahead.lookup = debounce(typeahead.lookup, 500, { leading: true });
}
}
@ -158,7 +158,7 @@ export function sqlPartEditorDirective(templateSrv: any) {
};
function addElementsAndCompile() {
_.each(partDef.params, (param: any, index: number) => {
each(partDef.params, (param: any, index: number) => {
if (param.optional && part.params.length <= index) {
return;
}
@ -174,10 +174,10 @@ export function sqlPartEditorDirective(templateSrv: any) {
$paramLink.appendTo($paramsContainer);
$input.appendTo($paramsContainer);
$input.blur(_.partial(inputBlur, $input, index));
$input.blur(partial(inputBlur, $input, index));
$input.keyup(inputKeyDown);
$input.keypress(_.partial(inputKeyPress, index));
$paramLink.click(_.partial(clickFuncParam, index));
$input.keypress(partial(inputKeyPress, index));
$paramLink.click(partial(clickFuncParam, index));
addTypeahead($input, param, index);
});

View File

@ -1,4 +1,4 @@
import _ from 'lodash';
import { isArray } from 'lodash';
import coreModule from '../core_module';
export function arrayJoin() {
@ -13,7 +13,7 @@ export function arrayJoin() {
}
function join_array(text: string) {
if (_.isArray(text)) {
if (isArray(text)) {
return ((text || '') as any).join(',');
} else {
return text;

View File

@ -1,4 +1,4 @@
import _ from 'lodash';
import { each, reduce } from 'lodash';
import $ from 'jquery';
import coreModule from '../core_module';
@ -32,8 +32,8 @@ export function dropdownTypeahead($compile: any) {
if (attrs.ngModel) {
$scope.$watch('model', (newValue: any) => {
_.each($scope.menuItems, (item) => {
_.each(item.submenu, (subItem) => {
each($scope.menuItems, (item) => {
each(item.submenu, (subItem) => {
if (subItem.value === newValue) {
$button.html(subItem.text);
}
@ -42,14 +42,14 @@ export function dropdownTypeahead($compile: any) {
});
}
const typeaheadValues = _.reduce(
const typeaheadValues = reduce(
$scope.menuItems,
(memo: any[], value, index) => {
if (!value.submenu) {
value.click = 'menuItemSelected(' + index + ')';
memo.push(value.text);
} else {
_.each(value.submenu, (item, subIndex) => {
each(value.submenu, (item, subIndex) => {
item.click = 'menuItemSelected(' + index + ',' + subIndex + ')';
memo.push(value.text + ' ' + item.text);
});
@ -84,8 +84,8 @@ export function dropdownTypeahead($compile: any) {
items: 10,
updater: (value: string) => {
const result: any = {};
_.each($scope.menuItems, (menuItem) => {
_.each(menuItem.submenu, (submenuItem) => {
each($scope.menuItems, (menuItem) => {
each(menuItem.submenu, (submenuItem) => {
if (value === menuItem.text + ' ' + submenuItem.text) {
result.$subItem = submenuItem;
result.$item = menuItem;
@ -172,8 +172,8 @@ export function dropdownTypeahead2($compile: any) {
if (attrs.ngModel) {
$scope.$watch('model', (newValue: any) => {
_.each($scope.menuItems, (item) => {
_.each(item.submenu, (subItem) => {
each($scope.menuItems, (item) => {
each(item.submenu, (subItem) => {
if (subItem.value === newValue) {
$button.html(subItem.text);
}
@ -182,14 +182,14 @@ export function dropdownTypeahead2($compile: any) {
});
}
const typeaheadValues = _.reduce(
const typeaheadValues = reduce(
$scope.menuItems,
(memo: any[], value, index) => {
if (!value.submenu) {
value.click = 'menuItemSelected(' + index + ')';
memo.push(value.text);
} else {
_.each(value.submenu, (item, subIndex) => {
each(value.submenu, (item, subIndex) => {
item.click = 'menuItemSelected(' + index + ',' + subIndex + ')';
memo.push(value.text + ' ' + item.text);
});
@ -224,8 +224,8 @@ export function dropdownTypeahead2($compile: any) {
items: 10,
updater: (value: string) => {
const result: any = {};
_.each($scope.menuItems, (menuItem) => {
_.each(menuItem.submenu, (submenuItem) => {
each($scope.menuItems, (menuItem) => {
each(menuItem.submenu, (submenuItem) => {
if (value === menuItem.text + ' ' + submenuItem.text) {
result.$subItem = submenuItem;
result.$item = menuItem;

View File

@ -1,4 +1,4 @@
import _ from 'lodash';
import { debounce, find, indexOf, map, escape, unescape } from 'lodash';
import $ from 'jquery';
import coreModule from '../core_module';
import { TemplateSrv } from 'app/features/templating/template_srv';
@ -43,7 +43,7 @@ export function metricSegment($compile: any, $sce: any, templateSrv: TemplateSrv
}
$scope.$apply(() => {
const selected: any = _.find($scope.altSegments, { value: value });
const selected: any = find($scope.altSegments, { value: value });
if (selected) {
segment.value = selected.value;
segment.html = selected.html || $sce.trustAsHtml(templateSrv.highlightVariablesAsHtml(selected.value));
@ -87,14 +87,14 @@ export function metricSegment($compile: any, $sce: any, templateSrv: TemplateSrv
$scope.$apply(() => {
$scope.getOptions({ $query: query }).then((altSegments: any) => {
$scope.altSegments = altSegments;
options = _.map($scope.altSegments, (alt) => {
return _.escape(alt.value);
options = map($scope.altSegments, (alt) => {
return escape(alt.value);
});
// add custom values
if (segment.custom !== 'false') {
if (!segment.fake && _.indexOf(options, segment.value) === -1) {
options.unshift(_.escape(segment.value));
if (!segment.fake && indexOf(options, segment.value) === -1) {
options.unshift(escape(segment.value));
}
}
@ -104,7 +104,7 @@ export function metricSegment($compile: any, $sce: any, templateSrv: TemplateSrv
};
$scope.updater = (value: string) => {
value = _.unescape(value);
value = unescape(value);
if (value === segment.value) {
clearTimeout(cancelBlur);
$input.focus();
@ -152,7 +152,7 @@ export function metricSegment($compile: any, $sce: any, templateSrv: TemplateSrv
};
if (debounceLookup) {
typeahead.lookup = _.debounce(typeahead.lookup, 500, { leading: true });
typeahead.lookup = debounce(typeahead.lookup, 500, { leading: true });
}
$button.keydown((evt) => {
@ -203,7 +203,7 @@ export function metricSegmentModel(uiSegmentSrv: any) {
let cachedOptions: any;
$scope.valueToSegment = (value: any) => {
const option: any = _.find($scope.options, { value: value });
const option: any = find($scope.options, { value: value });
const segment = {
cssClass: attrs.cssClass,
custom: attrs.custom,
@ -218,14 +218,14 @@ export function metricSegmentModel(uiSegmentSrv: any) {
if ($scope.options) {
cachedOptions = $scope.options;
return Promise.resolve(
_.map($scope.options, (option) => {
map($scope.options, (option) => {
return { value: option.text };
})
);
} else {
return $scope.getOptions().then((options: any) => {
cachedOptions = options;
return _.map(options, (option) => {
return map(options, (option) => {
if (option.html) {
return option;
}
@ -237,7 +237,7 @@ export function metricSegmentModel(uiSegmentSrv: any) {
$scope.onSegmentChange = () => {
if (cachedOptions) {
const option: any = _.find(cachedOptions, { text: $scope.segment.value });
const option: any = find(cachedOptions, { text: $scope.segment.value });
if (option && option.value !== $scope.property) {
$scope.property = option.value;
} else if (attrs.custom !== 'false') {

View File

@ -1,4 +1,4 @@
import _ from 'lodash';
import { isArray, isNull, isObject, isUndefined } from 'lodash';
import angular from 'angular';
import coreModule from '../core_module';
import { getTemplateSrv, TemplateSrv } from 'app/features/templating/template_srv';
@ -12,7 +12,7 @@ coreModule.filter('stringSort', () => {
coreModule.filter('slice', () => {
return (arr: any[], start: any, end: any) => {
if (!_.isUndefined(arr)) {
if (!isUndefined(arr)) {
return arr.slice(start, end);
}
return arr;
@ -21,10 +21,10 @@ coreModule.filter('slice', () => {
coreModule.filter('stringify', () => {
return (arr: any[]) => {
if (_.isObject(arr) && !_.isArray(arr)) {
if (isObject(arr) && !isArray(arr)) {
return angular.toJson(arr);
} else {
return _.isNull(arr) ? null : arr.toString();
return isNull(arr) ? null : arr.toString();
}
};
});

View File

@ -1,6 +1,6 @@
import $ from 'jquery';
import angular from 'angular';
import _ from 'lodash';
import { extend } from 'lodash';
const $win = $(window);
@ -30,7 +30,7 @@ $.fn.place_tt = (() => {
'$rootScope',
($compile, $rootScope) => {
const tmpScope = $rootScope.$new(true);
_.extend(tmpScope, opts.scopeData);
extend(tmpScope, opts.scopeData);
$compile($tooltip)(tmpScope);
tmpScope.$digest();

View File

@ -1,3 +1,4 @@
// eslint-disable-next-line lodash/import-scope
import _ from 'lodash';
/*

View File

@ -1,4 +1,4 @@
import _ from 'lodash';
import { size } from 'lodash';
import { colors, ansicolor } from '@grafana/ui';
import {
@ -399,7 +399,7 @@ export function logSeriesToLogsModel(logSeries: DataFrame[]): LogsModel | undefi
// Meta data to display in status
const meta: LogsMetaItem[] = [];
if (_.size(commonLabels) > 0) {
if (size(commonLabels) > 0) {
meta.push({
label: 'Common labels',
value: commonLabels,

View File

@ -1,6 +1,6 @@
import coreModule from 'app/core/core_module';
import config from 'app/core/config';
import _ from 'lodash';
import { find, isNumber } from 'lodash';
import { NavModel } from '@grafana/data';
export class NavModelSrv {
@ -12,7 +12,7 @@ export class NavModelSrv {
}
getCfgNode() {
return _.find(this.navItems, { id: 'cfg' });
return find(this.navItems, { id: 'cfg' });
}
getNav(...args: Array<string | number>) {
@ -23,12 +23,12 @@ export class NavModelSrv {
for (const id of args) {
// if its a number then it's the index to use for main
if (_.isNumber(id)) {
if (isNumber(id)) {
nav.main = nav.breadcrumbs[id];
break;
}
const node: any = _.find(children, { id: id });
const node: any = find(children, { id: id });
nav.breadcrumbs.push(node);
nav.node = node;
nav.main = node;

View File

@ -1,6 +1,6 @@
import angular from 'angular';
import coreModule from 'app/core/core_module';
import _ from 'lodash';
import { assign } from 'lodash';
import {
AngularComponent,
@ -16,7 +16,7 @@ export class AngularLoader implements AngularLoaderInterface {
load(elem: any, scopeProps: any, template: string): AngularComponent {
const scope = this.$rootScope.$new();
_.assign(scope, scopeProps);
assign(scope, scopeProps);
const compiledElem = this.$compile(template)(scope);
const rootNode = angular.element(elem);

View File

@ -1,5 +1,5 @@
import config from '../../core/config';
import _ from 'lodash';
import { extend } from 'lodash';
import coreModule from 'app/core/core_module';
import { rangeUtil } from '@grafana/data';
import { AccessControlAction, AccessControlScope, UserPermission } from 'app/types';
@ -35,7 +35,7 @@ export class User {
this.hasEditPermissionInFolders = false;
this.email = undefined;
if (config.bootData.user) {
_.extend(this, config.bootData.user);
extend(this, config.bootData.user);
}
}
}

View File

@ -1,5 +1,5 @@
import store from 'app/core/store';
import _ from 'lodash';
import { filter, isArray, isNumber } from 'lodash';
import config from 'app/core/config';
export class ImpressionSrv {
@ -10,7 +10,7 @@ export class ImpressionSrv {
let impressions = [];
if (store.exists(impressionsKey)) {
impressions = JSON.parse(store.get(impressionsKey));
if (!_.isArray(impressions)) {
if (!isArray(impressions)) {
impressions = [];
}
}
@ -32,8 +32,8 @@ export class ImpressionSrv {
impressions = JSON.parse(impressions);
impressions = _.filter(impressions, (el) => {
return _.isNumber(el);
impressions = filter(impressions, (el) => {
return isNumber(el);
});
return impressions;

View File

@ -1,4 +1,4 @@
import _ from 'lodash';
import { extend } from 'lodash';
import coreModule from 'app/core/core_module';
// @ts-ignore
import Drop from 'tether-drop';
@ -20,7 +20,7 @@ function popoverSrv(this: any, $compile: any, $rootScope: GrafanaRootScope, $tim
openDrop = null;
}
const scope = _.extend($rootScope.$new(true), options.model);
const scope = extend($rootScope.$new(true), options.model);
let drop: any;
const cleanUp = () => {

View File

@ -1,4 +1,4 @@
import _ from 'lodash';
import { clone, keys, sortBy, take, values } from 'lodash';
import impressionSrv from 'app/core/services/impression_srv';
import store from 'app/core/store';
@ -29,7 +29,7 @@ export class SearchSrv {
}
private queryForRecentDashboards(): Promise<DashboardSearchHit[]> {
const dashIds: number[] = _.take(impressionSrv.getDashboardOpened(), 30);
const dashIds: number[] = take(impressionSrv.getDashboardOpened(), 30);
if (dashIds.length === 0) {
return Promise.resolve([]);
}
@ -63,7 +63,7 @@ export class SearchSrv {
search(options: any) {
const sections: any = {};
const promises = [];
const query = _.clone(options);
const query = clone(options);
const filters = hasFilters(options) || query.folderIds?.length > 0;
query.folderIds = query.folderIds || [];
@ -93,7 +93,7 @@ export class SearchSrv {
);
return Promise.all(promises).then(() => {
return _.sortBy(_.values(sections), 'score');
return sortBy(values(sections), 'score');
});
}
@ -113,7 +113,7 @@ export class SearchSrv {
items: [],
url: hit.url,
icon: 'folder',
score: _.keys(sections).length,
score: keys(sections).length,
type: hit.type,
};
}
@ -134,7 +134,7 @@ export class SearchSrv {
url: hit.folderUrl,
items: [],
icon: 'folder-open',
score: _.keys(sections).length,
score: keys(sections).length,
type: DashboardSearchItemType.DashFolder,
};
} else {
@ -143,7 +143,7 @@ export class SearchSrv {
title: 'General',
items: [],
icon: 'folder-open',
score: _.keys(sections).length,
score: keys(sections).length,
type: DashboardSearchItemType.DashFolder,
};
}

Some files were not shown because too many files have changed in this diff Show More