diff --git a/client/.babelrc b/client/.babelrc index 86c445f545..431d458d29 100644 --- a/client/.babelrc +++ b/client/.babelrc @@ -1,3 +1,4 @@ { + "plugins": ["lodash"], "presets": ["es2015", "react"] } diff --git a/client/app/scripts/actions/app-actions.js b/client/app/scripts/actions/app-actions.js index eff78794b7..d248c33873 100644 --- a/client/app/scripts/actions/app-actions.js +++ b/client/app/scripts/actions/app-actions.js @@ -35,11 +35,11 @@ export function toggleHelp() { } -export function sortOrderChanged(sortBy, sortedDesc) { +export function sortOrderChanged(sortedBy, sortedDesc) { return (dispatch, getState) => { dispatch({ type: ActionTypes.SORT_ORDER_CHANGED, - sortBy, sortedDesc + sortedBy, sortedDesc }); updateRoute(getState); }; diff --git a/client/app/scripts/charts/edge-container.js b/client/app/scripts/charts/edge-container.js index 8a1defec32..81c1d2bb0d 100644 --- a/client/app/scripts/charts/edge-container.js +++ b/client/app/scripts/charts/edge-container.js @@ -1,9 +1,9 @@ -import _ from 'lodash'; import React from 'react'; import { connect } from 'react-redux'; import { Motion, spring } from 'react-motion'; import { Map as makeMap } from 'immutable'; import { line, curveBasis } from 'd3-shape'; +import { each, omit, times, constant } from 'lodash'; import { uniformSelect } from '../utils/array-utils'; import { round } from '../utils/math-utils'; @@ -24,7 +24,7 @@ const spline = line() const buildPath = (points, layoutPrecision) => { const extracted = []; - _.each(points, (value, key) => { + each(points, (value, key) => { const axis = key[0]; const index = key.slice(1); if (!extracted[index]) { @@ -57,7 +57,7 @@ class EdgeContainer extends React.Component { render() { const { layoutPrecision, points } = this.props; - const other = _.omit(this.props, 'points'); + const other = omit(this.props, 'points'); if (layoutPrecision === 0) { const path = spline(points.toJS()); @@ -88,7 +88,7 @@ class EdgeContainer extends React.Component { if (pointsMissing > 0) { // Whenever there are some waypoints missing, we simply populate the beginning of the // array with the first element, as this leaves the curve interpolation unchanged. - nextPoints = _.times(pointsMissing, _.constant(nextPoints[0])).concat(nextPoints); + nextPoints = times(pointsMissing, constant(nextPoints[0])).concat(nextPoints); } else if (pointsMissing < 0) { // If there are 'too many' waypoints given by dagre, we select a sub-array of // uniformly distributed indices. Note that it is very important to keep the first diff --git a/client/app/scripts/charts/node-container.js b/client/app/scripts/charts/node-container.js index 88c4264e21..92455a8adf 100644 --- a/client/app/scripts/charts/node-container.js +++ b/client/app/scripts/charts/node-container.js @@ -1,5 +1,5 @@ -import _ from 'lodash'; import React from 'react'; +import { omit } from 'lodash'; import { connect } from 'react-redux'; import { Motion, spring } from 'react-motion'; @@ -11,7 +11,7 @@ class NodeContainer extends React.Component { const { dx, dy, focused, layoutPrecision, zoomScale } = this.props; const animConfig = [80, 20]; // stiffness, damping const scaleFactor = focused ? (1 / zoomScale) : 1; - const other = _.omit(this.props, 'dx', 'dy'); + const other = omit(this.props, 'dx', 'dy'); return ( { if (edge.get('source') === props.selectedNodeId || edge.get('target') === props.selectedNodeId - || _.includes(adjacentLayoutNodeIds, edge.get('source')) - || _.includes(adjacentLayoutNodeIds, edge.get('target'))) { + || includes(adjacentLayoutNodeIds, edge.get('source')) + || includes(adjacentLayoutNodeIds, edge.get('target'))) { const source = stateNodes.get(edge.get('source')); const target = stateNodes.get(edge.get('target')); return edge.set('points', fromJS([ diff --git a/client/app/scripts/charts/nodes-grid.js b/client/app/scripts/charts/nodes-grid.js index 0d26f182e3..23da67dcaa 100644 --- a/client/app/scripts/charts/nodes-grid.js +++ b/client/app/scripts/charts/nodes-grid.js @@ -90,12 +90,12 @@ class NodesGrid extends React.Component { this.props.clickNode(node.id, node.label, el.getBoundingClientRect()); } - onSortChange(sortBy, sortedDesc) { - this.props.sortOrderChanged(sortBy, sortedDesc); + onSortChange(sortedBy, sortedDesc) { + this.props.sortOrderChanged(sortedBy, sortedDesc); } render() { - const { margins, nodes, height, gridSortBy, gridSortedDesc, + const { margins, nodes, height, gridSortedBy, gridSortedDesc, searchNodeMatches = makeMap(), searchQuery } = this.props; const cmpStyle = { height, @@ -129,7 +129,7 @@ class NodesGrid extends React.Component { topologyId={this.props.currentTopologyId} onSortChange={this.onSortChange} onClickRow={this.onClickRow} - sortBy={gridSortBy} + sortedBy={gridSortedBy} sortedDesc={gridSortedDesc} selectedNodeId={this.props.selectedNodeId} limit={1000} @@ -144,7 +144,7 @@ class NodesGrid extends React.Component { function mapStateToProps(state) { return { nodes: nodesSelector(state), - gridSortBy: state.get('gridSortBy'), + gridSortedBy: state.get('gridSortedBy'), gridSortedDesc: state.get('gridSortedDesc'), currentTopology: state.get('currentTopology'), currentTopologyId: state.get('currentTopologyId'), diff --git a/client/app/scripts/components/debug-toolbar.js b/client/app/scripts/components/debug-toolbar.js index 7a0ac7b65e..ff6a8873c3 100644 --- a/client/app/scripts/components/debug-toolbar.js +++ b/client/app/scripts/components/debug-toolbar.js @@ -1,8 +1,8 @@ /* eslint react/jsx-no-bind: "off" */ import React from 'react'; -import _ from 'lodash'; import Perf from 'react-addons-perf'; import { connect } from 'react-redux'; +import { sampleSize, sample, random, range, flattenDeep } from 'lodash'; import { fromJS, Set as makeSet } from 'immutable'; import { hsl } from 'd3-color'; @@ -28,7 +28,7 @@ ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor i voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.`; -const sample = (collection, n = 4) => _.sampleSize(collection, _.random(n)); +const sampleArray = (collection, n = 4) => sampleSize(collection, random(n)); const shapeTypes = { @@ -39,7 +39,7 @@ const shapeTypes = { }; -const LABEL_PREFIXES = _.range('A'.charCodeAt(), 'Z'.charCodeAt() + 1) +const LABEL_PREFIXES = range('A'.charCodeAt(), 'Z'.charCodeAt() + 1) .map(n => String.fromCharCode(n)); @@ -80,7 +80,7 @@ function label(shape, stacked) { function addAllVariants(dispatch) { - const newNodes = _.flattenDeep(STACK_VARIANTS.map(stack => (SHAPES.map(s => { + const newNodes = flattenDeep(STACK_VARIANTS.map(stack => (SHAPES.map(s => { if (!stack) return [deltaAdd(label(s, stack), [], s, stack, 1)]; return NODE_COUNTS.map(n => deltaAdd(label(s, stack), [], s, stack, n)); })))); @@ -92,7 +92,7 @@ function addAllVariants(dispatch) { function addAllMetricVariants(availableMetrics) { - const newNodes = _.flattenDeep(METRIC_FILLS.map((v, i) => ( + const newNodes = flattenDeep(METRIC_FILLS.map((v, i) => ( SHAPES.map(s => [addMetrics(availableMetrics, deltaAdd(label(s) + i, [], s), v)]) ))); @@ -201,7 +201,7 @@ class DebugToolbar extends React.Component { // remove random node const ns = this.props.nodes; const nodeNames = ns.keySeq().toJS(); - const randomNode = _.sample(nodeNames); + const randomNode = sample(nodeNames); this.asyncDispatch(receiveNodesDelta({ remove: [randomNode] })); @@ -219,7 +219,7 @@ class DebugToolbar extends React.Component { // filter random node const ns = this.props.nodes; const nodeNames = ns.keySeq().toJS(); - const randomNode = _.sample(nodeNames); + const randomNode = sample(nodeNames); if (randomNode) { let nextNodes = ns.setIn([randomNode, 'filtered'], true); this.shortLivedNodes = this.shortLivedNodes.add(randomNode); @@ -240,9 +240,9 @@ class DebugToolbar extends React.Component { const nodeNames = ns.keySeq().toJS(); this.asyncDispatch(receiveNodesDelta({ add: this._addNodes(7), - update: sample(nodeNames).map(n => ({ + update: sampleArray(nodeNames).map(n => ({ id: n, - adjacency: sample(nodeNames), + adjacency: sampleArray(nodeNames), }), nodeNames.length), remove: this._removeNode(), })); @@ -251,18 +251,18 @@ class DebugToolbar extends React.Component { _addNodes(n, prefix = 'zing') { const ns = this.props.nodes; const nodeNames = ns.keySeq().toJS(); - const newNodeNames = _.range(ns.size, ns.size + n).map(i => ( + const newNodeNames = range(ns.size, ns.size + n).map(i => ( // `${randomLetter()}${randomLetter()}-zing` `${prefix}${i}` )); - const allNodes = _(nodeNames).concat(newNodeNames).value(); + const allNodes = nodeNames.concat(newNodeNames); return newNodeNames.map((name) => deltaAdd( name, - sample(allNodes), - _.sample(SHAPES), - _.sample(STACK_VARIANTS), - _.sample(NODE_COUNTS), - sample(NETWORKS, 10) + sampleArray(allNodes), + sample(SHAPES), + sample(STACK_VARIANTS), + sample(NODE_COUNTS), + sampleArray(NETWORKS, 10) )); } @@ -278,7 +278,7 @@ class DebugToolbar extends React.Component { _removeNode() { const ns = this.props.nodes; const nodeNames = ns.keySeq().toJS(); - return [nodeNames[_.random(nodeNames.length - 1)]]; + return [nodeNames[random(nodeNames.length - 1)]]; } removeNode() { diff --git a/client/app/scripts/components/loading.js b/client/app/scripts/components/loading.js index 2696f46b16..259b586423 100644 --- a/client/app/scripts/components/loading.js +++ b/client/app/scripts/components/loading.js @@ -1,5 +1,5 @@ import React from 'react'; -import _ from 'lodash'; +import { sample } from 'lodash'; import { findTopologyById } from '../utils/topology-utils'; import NodesError from '../charts/nodes-error'; @@ -41,7 +41,7 @@ export class Loading extends React.Component { super(props, context); this.state = { - template: _.sample(LOADING_TEMPLATES) + template: sample(LOADING_TEMPLATES) }; } diff --git a/client/app/scripts/components/node-details/__tests__/node-details-table-test.js b/client/app/scripts/components/node-details/__tests__/node-details-table-test.js index 37019ee530..23213d56a7 100644 --- a/client/app/scripts/components/node-details/__tests__/node-details-table-test.js +++ b/client/app/scripts/components/node-details/__tests__/node-details-table-test.js @@ -68,7 +68,7 @@ describe('NodeDetailsTable', () => { @@ -89,7 +89,7 @@ describe('NodeDetailsTable', () => { diff --git a/client/app/scripts/components/node-details/node-details-controls.js b/client/app/scripts/components/node-details/node-details-controls.js index 703d5f79e1..87a45df994 100644 --- a/client/app/scripts/components/node-details/node-details-controls.js +++ b/client/app/scripts/components/node-details/node-details-controls.js @@ -1,5 +1,5 @@ import React from 'react'; -import _ from 'lodash'; +import { sortBy } from 'lodash'; import NodeDetailsControlButton from './node-details-control-button'; @@ -18,7 +18,7 @@ export default function NodeDetailsControls({controls, error, nodeId, pending}) {error} } - {_.sortBy(controls, 'rank').map(control => )} {controls && } diff --git a/client/app/scripts/components/node-details/node-details-table.js b/client/app/scripts/components/node-details/node-details-table.js index 5a441c46fd..1b464fe05e 100644 --- a/client/app/scripts/components/node-details/node-details-table.js +++ b/client/app/scripts/components/node-details/node-details-table.js @@ -1,6 +1,6 @@ -import _ from 'lodash'; import React from 'react'; import classNames from 'classnames'; +import { find, get, union, sortBy, groupBy, concat } from 'lodash'; import ShowMore from '../show-more'; import NodeDetailsTableRow from './node-details-table-row'; @@ -57,16 +57,16 @@ const COLUMN_WIDTHS = { }; -function getDefaultSortBy(columns, nodes) { +function getDefaultSortedBy(columns, nodes) { // default sorter specified by columns - const defaultSortColumn = _.find(columns, {defaultSort: true}); + const defaultSortColumn = find(columns, {defaultSort: true}); if (defaultSortColumn) { return defaultSortColumn.id; } // otherwise choose first metric - const firstNodeWithMetrics = _.find(nodes, n => _.get(n, ['metrics', 0])); + const firstNodeWithMetrics = find(nodes, n => get(n, ['metrics', 0])); if (firstNodeWithMetrics) { - return _.get(firstNodeWithMetrics, ['metrics', 0, 'id']); + return get(firstNodeWithMetrics, ['metrics', 0, 'id']); } return 'label'; @@ -84,7 +84,7 @@ function maybeToLower(value) { function getNodeValue(node, header) { const fieldId = header && header.id; if (fieldId !== null) { - let field = _.union(node.metrics, node.metadata).find(f => f.id === fieldId); + let field = union(node.metrics, node.metadata).find(f => f.id === fieldId); if (field) { if (isIP(header)) { @@ -112,14 +112,14 @@ function getNodeValue(node, header) { } -function getValueForSortBy(sortByHeader) { - return (node) => maybeToLower(getNodeValue(node, sortByHeader)); +function getValueForSortedBy(sortedByHeader) { + return (node) => maybeToLower(getNodeValue(node, sortedByHeader)); } function getMetaDataSorters(nodes) { // returns an array of sorters that will take a node - return _.get(nodes, [0, 'metadata'], []).map((field, index) => node => { + return get(nodes, [0, 'metadata'], []).map((field, index) => node => { const nodeMetadataField = node.metadata && node.metadata[index]; if (nodeMetadataField) { if (isNumber(nodeMetadataField)) { @@ -133,7 +133,7 @@ function getMetaDataSorters(nodes) { function sortNodes(nodes, getValue, sortedDesc) { - const sortedNodes = _.sortBy( + const sortedNodes = sortBy( nodes, getValue, getMetaDataSorters(nodes) @@ -145,16 +145,16 @@ function sortNodes(nodes, getValue, sortedDesc) { } -function getSortedNodes(nodes, sortByHeader, sortedDesc) { - const getValue = getValueForSortBy(sortByHeader); - const withAndWithoutValues = _.groupBy(nodes, (n) => { +function getSortedNodes(nodes, sortedByHeader, sortedDesc) { + const getValue = getValueForSortedBy(sortedByHeader); + const withAndWithoutValues = groupBy(nodes, (n) => { const v = getValue(n); return v !== null && v !== undefined ? 'withValues' : 'withoutValues'; }); const withValues = sortNodes(withAndWithoutValues.withValues, getValue, sortedDesc); const withoutValues = sortNodes(withAndWithoutValues.withoutValues, getValue, sortedDesc); - return _.concat(withValues, withoutValues); + return concat(withValues, withoutValues); } @@ -188,19 +188,19 @@ export default class NodeDetailsTable extends React.Component { this.state = { limit: props.limit || this.DEFAULT_LIMIT, sortedDesc: this.props.sortedDesc, - sortBy: this.props.sortBy + sortedBy: this.props.sortedBy }; this.handleLimitClick = this.handleLimitClick.bind(this); } - handleHeaderClick(ev, headerId, currentSortBy, currentSortedDesc) { + handleHeaderClick(ev, headerId, currentSortedBy, currentSortedDesc) { ev.preventDefault(); const header = this.getColumnHeaders().find(h => h.id === headerId); - const sortBy = header.id; - const sortedDesc = header.id === currentSortBy + const sortedBy = header.id; + const sortedDesc = header.id === currentSortedBy ? !currentSortedDesc : defaultSortDesc(header); - this.setState({sortBy, sortedDesc}); - this.props.onSortChange(sortBy, sortedDesc); + this.setState({sortedBy, sortedDesc}); + this.props.onSortChange(sortedBy, sortedDesc); } handleLimitClick() { @@ -213,7 +213,7 @@ export default class NodeDetailsTable extends React.Component { return [{id: 'label', label: this.props.label}].concat(columns); } - renderHeaders(sortBy, sortedDesc) { + renderHeaders(sortedBy, sortedDesc) { if (!this.props.nodes || this.props.nodes.length === 0) { return null; } @@ -226,10 +226,10 @@ export default class NodeDetailsTable extends React.Component { {headers.map((header, i) => { const headerClasses = ['node-details-table-header', 'truncate']; const onHeaderClick = ev => { - this.handleHeaderClick(ev, header.id, sortBy, sortedDesc); + this.handleHeaderClick(ev, header.id, sortedBy, sortedDesc); }; // sort by first metric by default - const isSorted = header.id === sortBy; + const isSorted = header.id === sortedBy; const isSortedDesc = isSorted && sortedDesc; const isSortedAsc = isSorted && !isSortedDesc; @@ -261,13 +261,13 @@ export default class NodeDetailsTable extends React.Component { const { nodeIdKey, columns, topologyId, onClickRow, onMouseEnter, onMouseLeave, onMouseEnterRow, onMouseLeaveRow } = this.props; - const sortBy = this.state.sortBy || getDefaultSortBy(columns, this.props.nodes); - const sortByHeader = this.getColumnHeaders().find(h => h.id === sortBy); + const sortedBy = this.state.sortedBy || getDefaultSortedBy(columns, this.props.nodes); + const sortedByHeader = this.getColumnHeaders().find(h => h.id === sortedBy); const sortedDesc = this.state.sortedDesc !== null ? this.state.sortedDesc : - defaultSortDesc(sortByHeader); + defaultSortDesc(sortedByHeader); - let nodes = getSortedNodes(this.props.nodes, sortByHeader, sortedDesc); + let nodes = getSortedNodes(this.props.nodes, sortedByHeader, sortedDesc); const limited = nodes && this.state.limit > 0 && nodes.length > this.state.limit; const expanded = this.state.limit === 0; const notShown = nodes.length - this.state.limit; @@ -283,7 +283,7 @@ export default class NodeDetailsTable extends React.Component {
- {this.renderHeaders(sortBy, sortedDesc)} + {this.renderHeaders(sortedBy, sortedDesc)} @@ -319,5 +319,5 @@ NodeDetailsTable.defaultProps = { nodeIdKey: 'id', // key to identify a node in a row (used for topology links) onSortChange: () => {}, sortedDesc: null, - sortBy: null, + sortedBy: null, }; diff --git a/client/app/scripts/components/search.js b/client/app/scripts/components/search.js index 70fd88839b..1164baae19 100644 --- a/client/app/scripts/components/search.js +++ b/client/app/scripts/components/search.js @@ -2,7 +2,7 @@ import React from 'react'; import ReactDOM from 'react-dom'; import { connect } from 'react-redux'; import classnames from 'classnames'; -import _ from 'lodash'; +import { debounce } from 'lodash'; import { blurSearch, doSearch, focusSearch, showHelp } from '../actions/app-actions'; import { slugify } from '../utils/string-utils'; @@ -48,7 +48,7 @@ class Search extends React.Component { this.handleBlur = this.handleBlur.bind(this); this.handleChange = this.handleChange.bind(this); this.handleFocus = this.handleFocus.bind(this); - this.doSearch = _.debounce(this.doSearch.bind(this), 200); + this.doSearch = debounce(this.doSearch.bind(this), 200); this.state = { value: '' }; diff --git a/client/app/scripts/components/terminal.js b/client/app/scripts/components/terminal.js index 00380bb1cd..af2ce51da2 100644 --- a/client/app/scripts/components/terminal.js +++ b/client/app/scripts/components/terminal.js @@ -4,7 +4,7 @@ import React from 'react'; import ReactDOM from 'react-dom'; import { connect } from 'react-redux'; import classNames from 'classnames'; -import _ from 'lodash'; +import { debounce } from 'lodash'; import { clickCloseTerminal } from '../actions/app-actions'; import { getNeutralColor } from '../utils/color-utils'; @@ -98,7 +98,7 @@ class Terminal extends React.Component { this.handleCloseClick = this.handleCloseClick.bind(this); this.handlePopoutTerminal = this.handlePopoutTerminal.bind(this); this.handleResize = this.handleResize.bind(this); - this.handleResizeDebounced = _.debounce(this.handleResize, 500); + this.handleResizeDebounced = debounce(this.handleResize, 500); } createWebsocket(term) { diff --git a/client/app/scripts/constants/action-types.js b/client/app/scripts/constants/action-types.js index 4e9ab8c174..cb617363c3 100644 --- a/client/app/scripts/constants/action-types.js +++ b/client/app/scripts/constants/action-types.js @@ -1,4 +1,4 @@ -import _ from 'lodash'; +import { zipObject } from 'lodash'; const ACTION_TYPES = [ 'ADD_QUERY_FILTER', @@ -59,4 +59,4 @@ const ACTION_TYPES = [ 'SET_GRID_MODE', ]; -export default _.zipObject(ACTION_TYPES, ACTION_TYPES); +export default zipObject(ACTION_TYPES, ACTION_TYPES); diff --git a/client/app/scripts/reducers/root.js b/client/app/scripts/reducers/root.js index f6979fb74d..28a3fb36fa 100644 --- a/client/app/scripts/reducers/root.js +++ b/client/app/scripts/reducers/root.js @@ -1,5 +1,5 @@ -import _ from 'lodash'; import debug from 'debug'; +import { size, each, includes } from 'lodash'; import { fromJS, is as isDeepEqual, List as makeList, Map as makeMap, OrderedMap as makeOrderedMap, Set as makeSet } from 'immutable'; @@ -30,7 +30,7 @@ export const initialState = makeMap({ errorUrl: null, forceRelayout: false, gridMode: false, - gridSortBy: null, + gridSortedBy: null, gridSortedDesc: null, highlightedEdgeIds: makeSet(), highlightedNodeIds: makeSet(), @@ -173,7 +173,7 @@ export function rootReducer(state = initialState, action) { case ActionTypes.SORT_ORDER_CHANGED: { return state.merge({ - gridSortBy: action.sortBy, + gridSortedBy: action.sortedBy, gridSortedDesc: action.sortedDesc, }); } @@ -518,34 +518,34 @@ export function rootReducer(state = initialState, action) { if (!emptyMessage) { log('RECEIVE_NODES_DELTA', - 'remove', _.size(action.delta.remove), - 'update', _.size(action.delta.update), - 'add', _.size(action.delta.add)); + 'remove', size(action.delta.remove), + 'update', size(action.delta.update), + 'add', size(action.delta.add)); } state = state.set('errorUrl', null); // nodes that no longer exist - _.each(action.delta.remove, (nodeId) => { + each(action.delta.remove, (nodeId) => { // in case node disappears before mouseleave event if (state.get('mouseOverNodeId') === nodeId) { state = state.set('mouseOverNodeId', null); } - if (state.hasIn(['nodes', nodeId]) && _.includes(state.get('mouseOverEdgeId'), nodeId)) { + if (state.hasIn(['nodes', nodeId]) && includes(state.get('mouseOverEdgeId'), nodeId)) { state = state.set('mouseOverEdgeId', null); } state = state.deleteIn(['nodes', nodeId]); }); // update existing nodes - _.each(action.delta.update, (node) => { + each(action.delta.update, (node) => { if (state.hasIn(['nodes', node.id])) { state = state.updateIn(['nodes', node.id], n => n.merge(fromJS(node))); } }); // add new nodes - _.each(action.delta.add, (node) => { + each(action.delta.add, (node) => { state = state.setIn(['nodes', node.id], fromJS(node)); }); @@ -658,8 +658,8 @@ export function rootReducer(state = initialState, action) { pinnedMetricType: action.state.pinnedMetricType }); state = state.set('gridMode', action.state.topologyViewMode === 'grid'); - if (action.state.gridSortBy) { - state = state.set('gridSortBy', action.state.gridSortBy); + if (action.state.gridSortedBy) { + state = state.set('gridSortedBy', action.state.gridSortedBy); } if (action.state.gridSortedDesc !== undefined) { state = state.set('gridSortedDesc', action.state.gridSortedDesc); diff --git a/client/app/scripts/utils/data-generator-utils.js b/client/app/scripts/utils/data-generator-utils.js index e75a6d83ab..d32e049144 100644 --- a/client/app/scripts/utils/data-generator-utils.js +++ b/client/app/scripts/utils/data-generator-utils.js @@ -1,4 +1,4 @@ -import _ from 'lodash'; +import { zipObject } from 'lodash'; import { scaleLinear } from 'd3-scale'; import { extent } from 'd3-array'; @@ -122,7 +122,7 @@ function handleAdd(nodes) { function handleUpdated(updatedNodes, prevNodes) { - const modifiedNodesIndex = _.zipObject((updatedNodes || []).map(n => [n.id, n])); + const modifiedNodesIndex = zipObject((updatedNodes || []).map(n => [n.id, n])); return prevNodes.toIndexedSeq().toJS().map(n => ( Object.assign({}, mergeMetrics(n), modifiedNodesIndex[n.id]) )); diff --git a/client/app/scripts/utils/file-utils.js b/client/app/scripts/utils/file-utils.js index 78dd2efc04..33af43d55f 100644 --- a/client/app/scripts/utils/file-utils.js +++ b/client/app/scripts/utils/file-utils.js @@ -1,5 +1,5 @@ // adapted from https://github.com/NYTimes/svg-crowbar -import _ from 'lodash'; +import { each } from 'lodash'; const doctype = ''; const prefix = { @@ -18,7 +18,7 @@ function setInlineStyles(svg, target, emptySvgDeclarationComputed) { function explicitlySetStyle(element, targetEl) { const cSSStyleDeclarationComputed = getComputedStyle(element); let computedStyleStr = ''; - _.each(cSSStyleDeclarationComputed, key => { + each(cSSStyleDeclarationComputed, key => { const value = cSSStyleDeclarationComputed.getPropertyValue(key); if (value !== emptySvgDeclarationComputed.getPropertyValue(key) && !cssSkipValues[value]) { computedStyleStr += `${key}:${value};`; diff --git a/client/app/scripts/utils/metric-utils.js b/client/app/scripts/utils/metric-utils.js index 9ae8e04651..1d481f0fd7 100644 --- a/client/app/scripts/utils/metric-utils.js +++ b/client/app/scripts/utils/metric-utils.js @@ -1,4 +1,4 @@ -import _ from 'lodash'; +import { includes } from 'lodash'; import { scaleLog } from 'd3-scale'; import { formatMetricSvg } from './string-utils'; import { colors } from './color-utils'; @@ -36,7 +36,7 @@ export function getMetricValue(metric, size) { let valuePercentage = value === 0 ? 0 : value / m.max; let max = m.max; - if (_.includes(['load1', 'load5', 'load15'], m.id)) { + if (includes(['load1', 'load5', 'load15'], m.id)) { valuePercentage = loadScale(value); max = null; } diff --git a/client/app/scripts/utils/router-utils.js b/client/app/scripts/utils/router-utils.js index b957352760..ffc4d85f18 100644 --- a/client/app/scripts/utils/router-utils.js +++ b/client/app/scripts/utils/router-utils.js @@ -47,7 +47,7 @@ export function getUrlState(state) { pinnedSearches: state.get('pinnedSearches').toJS(), searchQuery: state.get('searchQuery'), selectedNodeId: state.get('selectedNodeId'), - gridSortBy: state.get('gridSortBy'), + gridSortedBy: state.get('gridSortedBy'), gridSortedDesc: state.get('gridSortedDesc'), topologyId: state.get('currentTopologyId'), topologyOptions: state.get('topologyOptions').toJS() // all options diff --git a/client/app/scripts/utils/search-utils.js b/client/app/scripts/utils/search-utils.js index 8c9f87a7e5..a4c192a902 100644 --- a/client/app/scripts/utils/search-utils.js +++ b/client/app/scripts/utils/search-utils.js @@ -1,5 +1,5 @@ import { Map as makeMap, Set as makeSet, List as makeList } from 'immutable'; -import _ from 'lodash'; +import { escapeRegExp } from 'lodash'; import { slugify } from './string-utils'; @@ -26,7 +26,7 @@ function makeRegExp(expression, options = 'i') { try { return new RegExp(expression, options); } catch (e) { - return new RegExp(_.escapeRegExp(expression), options); + return new RegExp(escapeRegExp(expression), options); } } diff --git a/client/app/scripts/utils/topology-utils.js b/client/app/scripts/utils/topology-utils.js index 3d214cd910..5a6709bcb8 100644 --- a/client/app/scripts/utils/topology-utils.js +++ b/client/app/scripts/utils/topology-utils.js @@ -1,4 +1,4 @@ -import _ from 'lodash'; +import { endsWith } from 'lodash'; import { Set as makeSet, List as makeList } from 'immutable'; @@ -54,7 +54,7 @@ export function findTopologyById(subTree, topologyId) { let foundTopology; subTree.forEach(topology => { - if (_.endsWith(topology.get('url'), topologyId)) { + if (endsWith(topology.get('url'), topologyId)) { foundTopology = topology; } if (!foundTopology && topology.has('sub_topologies')) { diff --git a/client/app/scripts/utils/update-buffer-utils.js b/client/app/scripts/utils/update-buffer-utils.js index d77706a708..341618364c 100644 --- a/client/app/scripts/utils/update-buffer-utils.js +++ b/client/app/scripts/utils/update-buffer-utils.js @@ -1,6 +1,6 @@ -import _ from 'lodash'; import debug from 'debug'; import Immutable from 'immutable'; +import { union, size, map, find, reject, each } from 'lodash'; import { receiveNodesDelta } from '../actions/app-actions'; @@ -42,17 +42,17 @@ function consolidateBuffer() { const first = deltaBuffer.first(); deltaBuffer = deltaBuffer.shift(); const second = deltaBuffer.first(); - let toAdd = _.union(first.add, second.add); - let toUpdate = _.union(first.update, second.update); - let toRemove = _.union(first.remove, second.remove); - log('Consolidating delta buffer', 'add', _.size(toAdd), 'update', - _.size(toUpdate), 'remove', _.size(toRemove)); + let toAdd = union(first.add, second.add); + let toUpdate = union(first.update, second.update); + let toRemove = union(first.remove, second.remove); + log('Consolidating delta buffer', 'add', size(toAdd), 'update', + size(toUpdate), 'remove', size(toRemove)); // check if an added node in first was updated in second -> add second update - toAdd = _.map(toAdd, node => { - const updateNode = _.find(second.update, {id: node.id}); + toAdd = map(toAdd, node => { + const updateNode = find(second.update, {id: node.id}); if (updateNode) { - toUpdate = _.reject(toUpdate, {id: node.id}); + toUpdate = reject(toUpdate, {id: node.id}); return updateNode; } return node; @@ -62,19 +62,19 @@ function consolidateBuffer() { // no action needed, successive updates are fine // check if an added node in first was removed in second -> dont add, dont remove - _.each(first.add, node => { - const removedNode = _.find(second.remove, {id: node.id}); + each(first.add, node => { + const removedNode = find(second.remove, {id: node.id}); if (removedNode) { - toAdd = _.reject(toAdd, {id: node.id}); - toRemove = _.reject(toRemove, {id: node.id}); + toAdd = reject(toAdd, {id: node.id}); + toRemove = reject(toRemove, {id: node.id}); } }); // check if an updated node in first was removed in second -> remove - _.each(first.update, node => { - const removedNode = _.find(second.remove, {id: node.id}); + each(first.update, node => { + const removedNode = find(second.remove, {id: node.id}); if (removedNode) { - toUpdate = _.reject(toUpdate, {id: node.id}); + toUpdate = reject(toUpdate, {id: node.id}); } }); @@ -82,8 +82,8 @@ function consolidateBuffer() { // remove -> add is fine for the store // update buffer - log('Consolidated delta buffer', 'add', _.size(toAdd), 'update', - _.size(toUpdate), 'remove', _.size(toRemove)); + log('Consolidated delta buffer', 'add', size(toAdd), 'update', + size(toUpdate), 'remove', size(toRemove)); deltaBuffer.set(0, { add: toAdd.length > 0 ? toAdd : null, update: toUpdate.length > 0 ? toUpdate : null, diff --git a/client/package.json b/client/package.json index 9a25ecf093..77b9b7d2f1 100644 --- a/client/package.json +++ b/client/package.json @@ -41,6 +41,7 @@ "babel-eslint": "5.0.0", "babel-jest": "17.0.2", "babel-loader": "6.2.8", + "babel-plugin-lodash": "3.2.10", "babel-preset-es2015": "6.18.0", "babel-preset-react": "6.16.0", "clean-webpack-plugin": "0.1.14", diff --git a/client/webpack.local.config.js b/client/webpack.local.config.js index 9eb6d26f80..0cdf1bbf92 100644 --- a/client/webpack.local.config.js +++ b/client/webpack.local.config.js @@ -36,10 +36,9 @@ module.exports = { './app/scripts/terminal-main', 'webpack-hot-middleware/client' ], - vendors: ['babel-polyfill', 'classnames', 'dagre', 'filesize', 'immutable', 'lodash', + vendors: ['babel-polyfill', 'classnames', 'dagre', 'filesize', 'immutable', 'moment', 'page', 'react', 'react-dom', 'react-motion', 'react-redux', 'redux', - 'redux-thunk', 'reqwest', 'xterm', - 'webpack-hot-middleware/client' + 'redux-thunk', 'reqwest', 'xterm', 'webpack-hot-middleware/client' ] }, diff --git a/client/webpack.production.config.js b/client/webpack.production.config.js index ae790879d2..3d92669dae 100644 --- a/client/webpack.production.config.js +++ b/client/webpack.production.config.js @@ -35,8 +35,8 @@ module.exports = { 'terminal-app': './app/scripts/terminal-main', // keep only some in here, to make vendors and app bundles roughly same size vendors: ['babel-polyfill', 'classnames', 'immutable', - 'lodash', 'react', 'react-dom', 'react-redux', - 'redux', 'redux-thunk'] + 'react', 'react-dom', 'react-redux', 'redux', 'redux-thunk' + ] }, output: {