mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
Get rid of Lodash mixins (#17737)
* Get rid of _.class mixin * Get rid of _.flattenWith * Get rid of _.isNumeric * Get rid of _.toggleInOut * Get rid of _.onceWithCb * Get rid of _.callEach * Get rid of _.organizeBy, _.pushAll, _.move * Delete Lodash webpackShim
This commit is contained in:
parent
af300c9963
commit
5628ac3052
51 changed files with 463 additions and 598 deletions
|
@ -1,14 +1,15 @@
|
|||
import angular from 'angular';
|
||||
import _ from 'lodash';
|
||||
import { uiModules } from 'ui/modules';
|
||||
import { createDashboardEditUrl } from 'plugins/kibana/dashboard/dashboard_constants';
|
||||
import { createLegacyClass } from 'ui/utils/legacy_class';
|
||||
|
||||
const module = uiModules.get('app/dashboard');
|
||||
|
||||
// Used only by the savedDashboards service, usually no reason to change this
|
||||
module.factory('SavedDashboard', function (courier, config) {
|
||||
// SavedDashboard constructor. Usually you'd interact with an instance of this.
|
||||
// ID is option, without it one will be generated on save.
|
||||
_.class(SavedDashboard).inherits(courier.SavedObject);
|
||||
createLegacyClass(SavedDashboard).inherits(courier.SavedObject);
|
||||
function SavedDashboard(id) {
|
||||
// Gives our SavedDashboard the properties of a SavedObject
|
||||
SavedDashboard.Super.call(this, {
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import _ from 'lodash';
|
||||
import 'ui/notify';
|
||||
import { uiModules } from 'ui/modules';
|
||||
|
||||
import { createLegacyClass } from 'ui/utils/legacy_class';
|
||||
|
||||
const module = uiModules.get('discover/saved_searches', [
|
||||
'kibana/notify',
|
||||
|
@ -9,7 +8,7 @@ const module = uiModules.get('discover/saved_searches', [
|
|||
]);
|
||||
|
||||
module.factory('SavedSearch', function (courier) {
|
||||
_.class(SavedSearch).inherits(courier.SavedObject);
|
||||
createLegacyClass(SavedSearch).inherits(courier.SavedObject);
|
||||
function SavedSearch(id) {
|
||||
courier.SavedObject.call(this, {
|
||||
type: SavedSearch.type,
|
||||
|
|
|
@ -9,6 +9,7 @@ import { fatalError, toastNotifications } from 'ui/notify';
|
|||
import 'ui/accessibility/kbn_ui_ace_keyboard_mode';
|
||||
import { castEsToKbnFieldTypeName } from '../../../../../../utils';
|
||||
import { SavedObjectsClientProvider } from 'ui/saved_objects';
|
||||
import { isNumeric } from 'ui/utils/numeric';
|
||||
|
||||
const location = 'SavedObject view';
|
||||
|
||||
|
@ -55,7 +56,7 @@ uiModules.get('apps/management')
|
|||
} catch (err) {
|
||||
field.value = field.value;
|
||||
}
|
||||
} else if (_.isNumeric(field.value)) {
|
||||
} else if (isNumeric(field.value)) {
|
||||
field.type = 'number';
|
||||
} else if (Array.isArray(field.value)) {
|
||||
field.type = 'array';
|
||||
|
|
|
@ -6,18 +6,18 @@
|
|||
* NOTE: It's a type of SavedObject, but specific to visualizations.
|
||||
*/
|
||||
|
||||
import _ from 'lodash';
|
||||
import { VisProvider } from 'ui/vis';
|
||||
import { uiModules } from 'ui/modules';
|
||||
import { updateOldState } from 'ui/vis/vis_update_state';
|
||||
import { VisualizeConstants } from 'plugins/kibana/visualize/visualize_constants';
|
||||
import { createLegacyClass } from 'ui/utils/legacy_class';
|
||||
|
||||
uiModules
|
||||
.get('app/visualize')
|
||||
.factory('SavedVis', function (config, $injector, courier, Promise, savedSearches, Private) {
|
||||
const Vis = Private(VisProvider);
|
||||
|
||||
_.class(SavedVis).inherits(courier.SavedObject);
|
||||
createLegacyClass(SavedVis).inherits(courier.SavedObject);
|
||||
function SavedVis(opts) {
|
||||
const self = this;
|
||||
opts = opts || {};
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import _ from 'lodash';
|
||||
import { move } from 'ui/utils/collection';
|
||||
|
||||
require('angular-sortable-view');
|
||||
require('plugins/timelion/directives/chart/chart');
|
||||
|
@ -27,7 +28,7 @@ app.directive('timelionCells', function () {
|
|||
|
||||
$scope.dropCell = function (item, partFrom, partTo, indexFrom, indexTo) {
|
||||
$scope.onSelect(indexTo);
|
||||
_.move($scope.sheet, indexFrom, indexTo);
|
||||
move($scope.sheet, indexFrom, indexTo);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { uiModules } from 'ui/modules';
|
||||
import _ from 'lodash';
|
||||
import { createLegacyClass } from 'ui/utils/legacy_class';
|
||||
const module = uiModules.get('app/timelion');
|
||||
|
||||
// Used only by the savedSheets service, usually no reason to change this
|
||||
|
@ -7,7 +7,7 @@ module.factory('SavedSheet', function (courier, config) {
|
|||
|
||||
// SavedSheet constructor. Usually you'd interact with an instance of this.
|
||||
// ID is option, without it one will be generated on save.
|
||||
_.class(SavedSheet).inherits(courier.SavedObject);
|
||||
createLegacyClass(SavedSheet).inherits(courier.SavedObject);
|
||||
function SavedSheet(id) {
|
||||
// Gives our SavedSheet the properties of a SavedObject
|
||||
courier.SavedObject.call(this, {
|
||||
|
|
|
@ -17,10 +17,7 @@ export function FieldFormat(params) {
|
|||
}
|
||||
|
||||
FieldFormat.from = function (converter) {
|
||||
_.class(FieldFormatFromConverter).inherits(FieldFormat);
|
||||
function FieldFormatFromConverter(params) {
|
||||
FieldFormatFromConverter.Super.call(this, params);
|
||||
}
|
||||
class FieldFormatFromConverter extends FieldFormat {}
|
||||
FieldFormatFromConverter.prototype._convert = converter;
|
||||
return FieldFormatFromConverter;
|
||||
};
|
||||
|
|
|
@ -3,8 +3,9 @@ import AggConfigResult from 'ui/vis/agg_config_result';
|
|||
import { TabifyTable } from 'ui/agg_response/tabify/_table';
|
||||
import { TabifyTableGroup } from 'ui/agg_response/tabify/_table_group';
|
||||
import { tabifyGetColumns } from 'ui/agg_response/tabify/_get_columns';
|
||||
import { createLegacyClass } from '../../utils/legacy_class';
|
||||
|
||||
_.class(SplitAcr).inherits(AggConfigResult);
|
||||
createLegacyClass(SplitAcr).inherits(AggConfigResult);
|
||||
function SplitAcr(agg, parent, key) {
|
||||
SplitAcr.Super.call(this, agg, parent, key, key);
|
||||
}
|
||||
|
|
|
@ -3,12 +3,13 @@ import sinon from 'sinon';
|
|||
import { BaseParamType } from '../../param_types/base';
|
||||
import { FieldParamType } from '../../param_types/field';
|
||||
import { OptionedParamType } from '../../param_types/optioned';
|
||||
import { createLegacyClass } from '../../../utils/legacy_class';
|
||||
|
||||
function ParamClassStub(parent, body) {
|
||||
const stub = sinon.spy(body || function () {
|
||||
stub.Super && stub.Super.call(this);
|
||||
});
|
||||
if (parent) _.class(stub).inherits(parent);
|
||||
if (parent) createLegacyClass(stub).inherits(parent);
|
||||
return stub;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import 'ui/filters/label';
|
||||
import _ from 'lodash';
|
||||
import { IndexedArray } from 'ui/indexed_array';
|
||||
import { FieldParamType } from './param_types/field';
|
||||
import { OptionedParamType } from './param_types/optioned';
|
||||
|
@ -7,6 +6,7 @@ import { RegexParamType } from './param_types/regex';
|
|||
import { StringParamType } from './param_types/string';
|
||||
import { JsonParamType } from './param_types/json';
|
||||
import { BaseParamType } from './param_types/base';
|
||||
import { createLegacyClass } from '../utils/legacy_class';
|
||||
|
||||
const paramTypeMap = {
|
||||
field: FieldParamType,
|
||||
|
@ -30,7 +30,7 @@ const paramTypeMap = {
|
|||
* @extends IndexedArray
|
||||
* @param {object[]} params - array of params that get new-ed up as AggParam objects as descibed above
|
||||
*/
|
||||
_.class(AggParams).inherits(IndexedArray);
|
||||
createLegacyClass(AggParams).inherits(IndexedArray);
|
||||
function AggParams(params) {
|
||||
AggParams.Super.call(this, {
|
||||
index: ['name'],
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
import _ from 'lodash';
|
||||
import { AggTypesAggTypeProvider } from 'ui/agg_types/agg_type';
|
||||
import { createLegacyClass } from '../../utils/legacy_class';
|
||||
|
||||
export function AggTypesBucketsBucketAggTypeProvider(Private) {
|
||||
const AggType = Private(AggTypesAggTypeProvider);
|
||||
|
||||
_.class(BucketAggType).inherits(AggType);
|
||||
createLegacyClass(BucketAggType).inherits(AggType);
|
||||
function BucketAggType(config) {
|
||||
BucketAggType.Super.call(this, config);
|
||||
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
import _ from 'lodash';
|
||||
import { AggTypesAggTypeProvider } from 'ui/agg_types/agg_type';
|
||||
import { fieldFormats } from 'ui/registry/field_formats';
|
||||
import { createLegacyClass } from '../../utils/legacy_class';
|
||||
|
||||
export function AggTypesMetricsMetricAggTypeProvider(Private) {
|
||||
const AggType = Private(AggTypesAggTypeProvider);
|
||||
|
||||
|
||||
_.class(MetricAggType).inherits(AggType);
|
||||
createLegacyClass(MetricAggType).inherits(AggType);
|
||||
function MetricAggType(config) {
|
||||
MetricAggType.Super.call(this, config);
|
||||
|
||||
|
|
|
@ -6,11 +6,11 @@ import 'ui/filters/field_type';
|
|||
import { IndexedArray } from 'ui/indexed_array';
|
||||
import { Notifier } from 'ui/notify';
|
||||
import { propFilter } from 'ui/filters/_prop_filter';
|
||||
|
||||
import { createLegacyClass } from '../../utils/legacy_class';
|
||||
|
||||
const notifier = new Notifier();
|
||||
|
||||
_.class(FieldParamType).inherits(BaseParamType);
|
||||
createLegacyClass(FieldParamType).inherits(BaseParamType);
|
||||
function FieldParamType(config) {
|
||||
FieldParamType.Super.call(this, config);
|
||||
}
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import _ from 'lodash';
|
||||
import editorHtml from '../controls/raw_json.html';
|
||||
import { BaseParamType } from './base';
|
||||
import { createLegacyClass } from '../../utils/legacy_class';
|
||||
|
||||
|
||||
_.class(JsonParamType).inherits(BaseParamType);
|
||||
createLegacyClass(JsonParamType).inherits(BaseParamType);
|
||||
function JsonParamType(config) {
|
||||
// force name override
|
||||
config = _.defaults(config, { name: 'json' });
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import _ from 'lodash';
|
||||
import { IndexedArray } from 'ui/indexed_array';
|
||||
import { BaseParamType } from './base';
|
||||
import { createLegacyClass } from '../../utils/legacy_class';
|
||||
|
||||
_.class(OptionedParamType).inherits(BaseParamType);
|
||||
createLegacyClass(OptionedParamType).inherits(BaseParamType);
|
||||
function OptionedParamType(config) {
|
||||
OptionedParamType.Super.call(this, config);
|
||||
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import _ from 'lodash';
|
||||
import editorHtml from '../controls/regular_expression.html';
|
||||
import { BaseParamType } from './base';
|
||||
import { createLegacyClass } from '../../utils/legacy_class';
|
||||
|
||||
_.class(RegexParamType).inherits(BaseParamType);
|
||||
createLegacyClass(RegexParamType).inherits(BaseParamType);
|
||||
function RegexParamType(config) {
|
||||
_.defaults(config, { pattern: '' });
|
||||
RegexParamType.Super.call(this, config);
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import _ from 'lodash';
|
||||
import editorHtml from '../controls/string.html';
|
||||
import { BaseParamType } from './base';
|
||||
import { createLegacyClass } from '../../utils/legacy_class';
|
||||
|
||||
_.class(StringParamType).inherits(BaseParamType);
|
||||
createLegacyClass(StringParamType).inherits(BaseParamType);
|
||||
function StringParamType(config) {
|
||||
StringParamType.Super.call(this, config);
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ import _ from 'lodash';
|
|||
import { Notifier } from 'ui/notify';
|
||||
import { SearchRequestProvider } from './search_request';
|
||||
import { SegmentedHandleProvider } from './segmented_handle';
|
||||
import { pushAll } from '../../../utils/collection';
|
||||
|
||||
export function SegmentedRequestProvider(Private, timefilter, config) {
|
||||
const SearchRequest = Private(SearchRequestProvider);
|
||||
|
@ -226,7 +227,7 @@ export function SegmentedRequestProvider(Private, timefilter, config) {
|
|||
const desiredSize = this._desiredSize;
|
||||
const sortFn = this._sortFn;
|
||||
|
||||
_.pushAll(hits, mergedHits);
|
||||
pushAll(hits, mergedHits);
|
||||
|
||||
if (sortFn) {
|
||||
notify.event('resort rows', function () {
|
||||
|
|
|
@ -4,6 +4,8 @@ import AggConfigResult from 'ui/vis/agg_config_result';
|
|||
import { FilterBarClickHandlerProvider } from 'ui/filter_bar/filter_bar_click_handler';
|
||||
import { uiModules } from 'ui/modules';
|
||||
import tableCellFilterHtml from './partials/table_cell_filter.html';
|
||||
import { isNumeric } from '../utils/numeric';
|
||||
|
||||
const module = uiModules.get('kibana');
|
||||
|
||||
module.directive('kbnRows', function ($compile, $rootScope, getAppState, Private) {
|
||||
|
@ -60,7 +62,7 @@ module.directive('kbnRows', function ($compile, $rootScope, getAppState, Private
|
|||
|
||||
// TODO: It would be better to actually check the type of the field, but we don't have
|
||||
// access to it here. This may become a problem with the switch to BigNumber
|
||||
if (_.isNumeric(contents)) {
|
||||
if (isNumeric(contents)) {
|
||||
$cell.addClass('numeric-value');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import _ from 'lodash';
|
||||
import dragula from 'dragula';
|
||||
import { uiModules } from 'ui/modules';
|
||||
import { move } from '../utils/collection';
|
||||
|
||||
uiModules
|
||||
.get('kibana')
|
||||
|
@ -82,7 +82,7 @@ uiModules
|
|||
const siblingIndex = getItemIndexFromElement(list, sibling);
|
||||
|
||||
const toIndex = getTargetIndex(list, fromIndex, siblingIndex);
|
||||
_.move(list, item, toIndex);
|
||||
move(list, item, toIndex);
|
||||
}
|
||||
|
||||
function getTargetIndex(list, fromIndex, siblingIndex) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import angular from 'angular';
|
||||
import _ from 'lodash';
|
||||
import { createLegacyClass } from './utils/legacy_class';
|
||||
|
||||
const canStack = (function () {
|
||||
const err = new Error();
|
||||
|
@ -30,7 +30,7 @@ export class KbnError {
|
|||
// http://stackoverflow.com/questions/33870684/why-doesnt-instanceof-work-on-instances-of-error-subclasses-under-babel-node
|
||||
// Hence we are inheriting from it this way, instead of using extends Error, and this will then preserve
|
||||
// instanceof checks.
|
||||
_.class(KbnError).inherits(Error);
|
||||
createLegacyClass(KbnError).inherits(Error);
|
||||
|
||||
/**
|
||||
* SearchTimeout error class
|
||||
|
|
|
@ -7,11 +7,12 @@
|
|||
import _ from 'lodash';
|
||||
import { fatalError } from 'ui/notify';
|
||||
import { SimpleEmitter } from 'ui/utils/simple_emitter';
|
||||
import { createLegacyClass } from './utils/legacy_class';
|
||||
|
||||
const location = 'EventEmitter';
|
||||
|
||||
export function EventsProvider(Private, Promise) {
|
||||
_.class(Events).inherits(SimpleEmitter);
|
||||
createLegacyClass(Events).inherits(SimpleEmitter);
|
||||
function Events() {
|
||||
Events.Super.call(this);
|
||||
this._listeners = {};
|
||||
|
|
|
@ -5,6 +5,7 @@ import expect from 'expect.js';
|
|||
import ngMock from 'ng_mock';
|
||||
import 'ui/private';
|
||||
import { EventsProvider } from 'ui/events';
|
||||
import { createLegacyClass } from '../../utils/legacy_class';
|
||||
|
||||
describe('Events', function () {
|
||||
require('test_utils/no_digest_promises').activateForSuite();
|
||||
|
@ -30,7 +31,7 @@ describe('Events', function () {
|
|||
});
|
||||
|
||||
it('should work with inherited objects', function () {
|
||||
_.class(MyEventedObject).inherits(Events);
|
||||
createLegacyClass(MyEventedObject).inherits(Events);
|
||||
function MyEventedObject() {
|
||||
MyEventedObject.Super.call(this);
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import { IndexedArray } from 'ui/indexed_array';
|
||||
import _ from 'lodash';
|
||||
import { IndexPatternsFieldProvider } from 'ui/index_patterns/_field';
|
||||
import { createLegacyClass } from '../utils/legacy_class';
|
||||
|
||||
export function IndexPatternsFieldListProvider(Private) {
|
||||
const Field = Private(IndexPatternsFieldProvider);
|
||||
|
||||
_.class(FieldList).inherits(IndexedArray);
|
||||
createLegacyClass(FieldList).inherits(IndexedArray);
|
||||
function FieldList(indexPattern, specs) {
|
||||
FieldList.Super.call(this, {
|
||||
index: ['name'],
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import _ from 'lodash';
|
||||
import moment from 'moment';
|
||||
import { IndexedArray } from 'ui/indexed_array';
|
||||
import { isNumeric } from '../utils/numeric';
|
||||
|
||||
export function IndexPatternsIntervalsProvider(timefilter) {
|
||||
|
||||
|
@ -52,7 +53,7 @@ export function IndexPatternsIntervalsProvider(timefilter) {
|
|||
val = bounds[bound];
|
||||
}
|
||||
|
||||
if (_.isNumeric(val)) val = moment().add(val, interval.name);
|
||||
if (isNumeric(val)) val = moment().add(val, interval.name);
|
||||
else if (!moment.isMoment(val)) val = moment(val);
|
||||
|
||||
return val.clone().utc()[extend](interval.startOf);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import _ from 'lodash';
|
||||
import { inflector } from './inflector';
|
||||
import { organizeBy } from '../utils/collection';
|
||||
|
||||
const pathGetter = _(_.get).rearg(1, 0).ary(2);
|
||||
const inflectIndex = inflector('by');
|
||||
|
@ -31,7 +32,7 @@ export class IndexedArray {
|
|||
Object.defineProperty(this, 'raw', { value: [] });
|
||||
|
||||
this._indexNames = _.union(
|
||||
this._setupIndex(config.group, inflectIndex, _.organizeBy),
|
||||
this._setupIndex(config.group, inflectIndex, organizeBy),
|
||||
this._setupIndex(config.index, inflectIndex, _.indexBy),
|
||||
this._setupIndex(config.order, inflectOrder, (raw, pluckValue) => {
|
||||
return [...raw].sort((itemA, itemB) => {
|
||||
|
|
|
@ -3,6 +3,7 @@ import $ from 'jquery';
|
|||
import { metadata } from 'ui/metadata';
|
||||
import { formatMsg, formatStack } from './lib';
|
||||
import fatalSplashScreen from './partials/fatal_splash_screen.html';
|
||||
import { callEach } from '../utils/function';
|
||||
|
||||
const {
|
||||
version,
|
||||
|
@ -45,7 +46,7 @@ function formatInfo() {
|
|||
export const fatalErrorInternals = {
|
||||
show: (err, location) => {
|
||||
if (firstFatal) {
|
||||
_.callEach(fatalCallbacks);
|
||||
callEach(fatalCallbacks);
|
||||
firstFatal = false;
|
||||
window.addEventListener('hashchange', function () {
|
||||
window.location.reload();
|
||||
|
|
|
@ -8,10 +8,11 @@
|
|||
* ability to destroy those mappings.
|
||||
*/
|
||||
|
||||
import _ from 'lodash';
|
||||
import { uiModules } from 'ui/modules';
|
||||
import { StateProvider } from 'ui/state_management/state';
|
||||
import 'ui/persisted_state';
|
||||
import { createLegacyClass } from '../utils/legacy_class';
|
||||
import { callEach } from '../utils/function';
|
||||
|
||||
const urlParam = '_a';
|
||||
|
||||
|
@ -21,7 +22,7 @@ export function AppStateProvider(Private, $rootScope, $location, $injector) {
|
|||
let persistedStates;
|
||||
let eventUnsubscribers;
|
||||
|
||||
_.class(AppState).inherits(State);
|
||||
createLegacyClass(AppState).inherits(State);
|
||||
function AppState(defaults) {
|
||||
// Initialize persistedStates. This object maps "prop" names to
|
||||
// PersistedState instances. These are used to make properties "stateful".
|
||||
|
@ -42,7 +43,7 @@ export function AppStateProvider(Private, $rootScope, $location, $injector) {
|
|||
AppState.prototype.destroy = function () {
|
||||
AppState.Super.prototype.destroy.call(this);
|
||||
AppState.getAppState._set(null);
|
||||
_.callEach(eventUnsubscribers);
|
||||
callEach(eventUnsubscribers);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
import _ from 'lodash';
|
||||
import { QueryString } from 'ui/utils/query_string';
|
||||
import { StateProvider } from 'ui/state_management/state';
|
||||
import { uiModules } from 'ui/modules';
|
||||
import { createLegacyClass } from '../utils/legacy_class';
|
||||
|
||||
const module = uiModules.get('kibana/global_state');
|
||||
|
||||
export function GlobalStateProvider(Private) {
|
||||
const State = Private(StateProvider);
|
||||
|
||||
_.class(GlobalState).inherits(State);
|
||||
createLegacyClass(GlobalState).inherits(State);
|
||||
function GlobalState(defaults) {
|
||||
GlobalState.Super.call(this, '_g', defaults);
|
||||
}
|
||||
|
|
|
@ -13,6 +13,8 @@ import { applyDiff } from 'ui/utils/diff_object';
|
|||
import { EventsProvider } from 'ui/events';
|
||||
import { fatalError, Notifier } from 'ui/notify';
|
||||
import 'ui/state_management/config_provider';
|
||||
import { createLegacyClass } from '../utils/legacy_class';
|
||||
import { callEach } from '../utils/function';
|
||||
|
||||
import {
|
||||
createStateHash,
|
||||
|
@ -23,7 +25,7 @@ import {
|
|||
export function StateProvider(Private, $rootScope, $location, stateManagementConfig, config, kbnUrl) {
|
||||
const Events = Private(EventsProvider);
|
||||
|
||||
_.class(State).inherits(Events);
|
||||
createLegacyClass(State).inherits(Events);
|
||||
function State(
|
||||
urlParam,
|
||||
defaults,
|
||||
|
@ -38,7 +40,7 @@ export function StateProvider(Private, $rootScope, $location, stateManagementCon
|
|||
this._hashedItemStore = hashedItemStore;
|
||||
|
||||
// When the URL updates we need to fetch the values from the URL
|
||||
this._cleanUpListeners = _.partial(_.callEach, [
|
||||
this._cleanUpListeners = _.partial(callEach, [
|
||||
// partial route update, no app reload
|
||||
$rootScope.$on('$routeUpdate', () => {
|
||||
this.fetch();
|
||||
|
|
|
@ -8,6 +8,7 @@ import { TimefilterLibDiffTimeProvider } from 'ui/timefilter/lib/diff_time';
|
|||
import { TimefilterLibDiffIntervalProvider } from 'ui/timefilter/lib/diff_interval';
|
||||
import uiRoutes from 'ui/routes';
|
||||
import { uiModules } from 'ui/modules';
|
||||
import { createLegacyClass } from '../utils/legacy_class';
|
||||
|
||||
uiRoutes
|
||||
.addSetupWork(function (timefilter) {
|
||||
|
@ -24,7 +25,7 @@ uiModules
|
|||
return obj.isValid() ? obj : stringTime;
|
||||
}
|
||||
|
||||
_.class(Timefilter).inherits(Events);
|
||||
createLegacyClass(Timefilter).inherits(Events);
|
||||
function Timefilter() {
|
||||
Timefilter.Super.call(this);
|
||||
|
||||
|
|
225
src/ui/public/utils/__tests__/collection.js
Normal file
225
src/ui/public/utils/__tests__/collection.js
Normal file
|
@ -0,0 +1,225 @@
|
|||
import expect from 'expect.js';
|
||||
import { groupBy } from 'lodash';
|
||||
import { move, pushAll, organizeBy } from '../collection';
|
||||
|
||||
describe('collection', () => {
|
||||
describe('move', function () {
|
||||
|
||||
it('accepts previous from->to syntax', function () {
|
||||
const list = [
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
8,
|
||||
1,
|
||||
1,
|
||||
];
|
||||
|
||||
expect(list[3]).to.be(1);
|
||||
expect(list[8]).to.be(8);
|
||||
|
||||
move(list, 8, 3);
|
||||
|
||||
expect(list[8]).to.be(1);
|
||||
expect(list[3]).to.be(8);
|
||||
});
|
||||
|
||||
it('moves an object up based on a function callback', function () {
|
||||
const list = [
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
];
|
||||
|
||||
expect(list[4]).to.be(0);
|
||||
expect(list[5]).to.be(1);
|
||||
expect(list[6]).to.be(0);
|
||||
|
||||
move(list, 5, false, function (v) {
|
||||
return v === 0;
|
||||
});
|
||||
|
||||
expect(list[4]).to.be(1);
|
||||
expect(list[5]).to.be(0);
|
||||
expect(list[6]).to.be(0);
|
||||
});
|
||||
|
||||
it('moves an object down based on a function callback', function () {
|
||||
const list = [
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
];
|
||||
|
||||
expect(list[4]).to.be(0);
|
||||
expect(list[5]).to.be(1);
|
||||
expect(list[6]).to.be(0);
|
||||
|
||||
move(list, 5, true, function (v) {
|
||||
return v === 0;
|
||||
});
|
||||
|
||||
expect(list[4]).to.be(0);
|
||||
expect(list[5]).to.be(0);
|
||||
expect(list[6]).to.be(1);
|
||||
});
|
||||
|
||||
it('moves an object up based on a where callback', function () {
|
||||
const list = [
|
||||
{ v: 1 },
|
||||
{ v: 1 },
|
||||
{ v: 1 },
|
||||
{ v: 1 },
|
||||
{ v: 0 },
|
||||
{ v: 1 },
|
||||
{ v: 0 },
|
||||
{ v: 1 },
|
||||
{ v: 1 },
|
||||
{ v: 1 },
|
||||
{ v: 1 },
|
||||
];
|
||||
|
||||
expect(list[4]).to.have.property('v', 0);
|
||||
expect(list[5]).to.have.property('v', 1);
|
||||
expect(list[6]).to.have.property('v', 0);
|
||||
|
||||
move(list, 5, false, { v: 0 });
|
||||
|
||||
expect(list[4]).to.have.property('v', 1);
|
||||
expect(list[5]).to.have.property('v', 0);
|
||||
expect(list[6]).to.have.property('v', 0);
|
||||
});
|
||||
|
||||
|
||||
it('moves an object down based on a where callback', function () {
|
||||
const list = [
|
||||
{ v: 1 },
|
||||
{ v: 1 },
|
||||
{ v: 1 },
|
||||
{ v: 1 },
|
||||
{ v: 0 },
|
||||
{ v: 1 },
|
||||
{ v: 0 },
|
||||
{ v: 1 },
|
||||
{ v: 1 },
|
||||
{ v: 1 },
|
||||
{ v: 1 },
|
||||
];
|
||||
|
||||
expect(list[4]).to.have.property('v', 0);
|
||||
expect(list[5]).to.have.property('v', 1);
|
||||
expect(list[6]).to.have.property('v', 0);
|
||||
|
||||
move(list, 5, true, { v: 0 });
|
||||
|
||||
expect(list[4]).to.have.property('v', 0);
|
||||
expect(list[5]).to.have.property('v', 0);
|
||||
expect(list[6]).to.have.property('v', 1);
|
||||
});
|
||||
|
||||
it('moves an object down based on a pluck callback', function () {
|
||||
const list = [
|
||||
{ id: 0, normal: true },
|
||||
{ id: 1, normal: true },
|
||||
{ id: 2, normal: true },
|
||||
{ id: 3, normal: true },
|
||||
{ id: 4, normal: true },
|
||||
{ id: 5, normal: false },
|
||||
{ id: 6, normal: true },
|
||||
{ id: 7, normal: true },
|
||||
{ id: 8, normal: true },
|
||||
{ id: 9, normal: true }
|
||||
];
|
||||
|
||||
expect(list[4]).to.have.property('id', 4);
|
||||
expect(list[5]).to.have.property('id', 5);
|
||||
expect(list[6]).to.have.property('id', 6);
|
||||
|
||||
move(list, 5, true, 'normal');
|
||||
|
||||
expect(list[4]).to.have.property('id', 4);
|
||||
expect(list[5]).to.have.property('id', 6);
|
||||
expect(list[6]).to.have.property('id', 5);
|
||||
});
|
||||
});
|
||||
|
||||
describe('pushAll', function () {
|
||||
it('pushes an entire array into another', function () {
|
||||
const a = [1, 2, 3, 4];
|
||||
const b = [5, 6, 7, 8];
|
||||
|
||||
const output = pushAll(b, a);
|
||||
expect(output).to.be(a);
|
||||
expect(a).to.eql([1, 2, 3, 4, 5, 6, 7, 8]);
|
||||
expect(b).to.eql([5, 6, 7, 8]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('organizeBy', function () {
|
||||
|
||||
it('it works', function () {
|
||||
const col = [
|
||||
{
|
||||
name: 'one',
|
||||
roles: ['user', 'admin', 'owner']
|
||||
},
|
||||
{
|
||||
name: 'two',
|
||||
roles: ['user']
|
||||
},
|
||||
{
|
||||
name: 'three',
|
||||
roles: ['user']
|
||||
},
|
||||
{
|
||||
name: 'four',
|
||||
roles: ['user', 'admin']
|
||||
}
|
||||
];
|
||||
|
||||
const resp = organizeBy(col, 'roles');
|
||||
expect(resp).to.have.property('user');
|
||||
expect(resp.user).to.have.length(4);
|
||||
|
||||
expect(resp).to.have.property('admin');
|
||||
expect(resp.admin).to.have.length(2);
|
||||
|
||||
expect(resp).to.have.property('owner');
|
||||
expect(resp.owner).to.have.length(1);
|
||||
});
|
||||
|
||||
it('behaves just like groupBy in normal scenarios', function () {
|
||||
const col = [
|
||||
{ name: 'one' },
|
||||
{ name: 'two' },
|
||||
{ name: 'three' },
|
||||
{ name: 'four' }
|
||||
];
|
||||
|
||||
const orgs = organizeBy(col, 'name');
|
||||
const groups = groupBy(col, 'name');
|
||||
expect(orgs).to.eql(groups);
|
||||
});
|
||||
});
|
||||
});
|
104
src/ui/public/utils/collection.js
Normal file
104
src/ui/public/utils/collection.js
Normal file
|
@ -0,0 +1,104 @@
|
|||
import _ from 'lodash';
|
||||
|
||||
/**
|
||||
* move an obj either up or down in the collection by
|
||||
* injecting it either before/after the prev/next obj that
|
||||
* satisfied the qualifier
|
||||
*
|
||||
* or, just from one index to another...
|
||||
*
|
||||
* @param {array} objs - the list to move the object within
|
||||
* @param {number|any} obj - the object that should be moved, or the index that the object is currently at
|
||||
* @param {number|boolean} below - the index to move the object to, or whether it should be moved up or down
|
||||
* @param {function} qualifier - a lodash-y callback, object = _.where, string = _.pluck
|
||||
* @return {array} - the objs argument
|
||||
*/
|
||||
export function move(objs, obj, below, qualifier) {
|
||||
const origI = _.isNumber(obj) ? obj : objs.indexOf(obj);
|
||||
if (origI === -1) return objs;
|
||||
|
||||
if (_.isNumber(below)) {
|
||||
// move to a specific index
|
||||
objs.splice(below, 0, objs.splice(origI, 1)[0]);
|
||||
return objs;
|
||||
}
|
||||
|
||||
below = !!below;
|
||||
qualifier = _.callback(qualifier);
|
||||
|
||||
const above = !below;
|
||||
const finder = below ? _.findIndex : _.findLastIndex;
|
||||
|
||||
// find the index of the next/previous obj that meets the qualifications
|
||||
const targetI = finder(objs, function (otherAgg, otherI) {
|
||||
if (below && otherI <= origI) return;
|
||||
if (above && otherI >= origI) return;
|
||||
return !!qualifier(otherAgg, otherI);
|
||||
});
|
||||
|
||||
if (targetI === -1) return objs;
|
||||
|
||||
// place the obj at it's new index
|
||||
objs.splice(targetI, 0, objs.splice(origI, 1)[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Like _.groupBy, but allows specifying multiple groups for a
|
||||
* single object.
|
||||
*
|
||||
* organizeBy([{ a: [1, 2, 3] }, { b: true, a: [1, 4] }], 'a')
|
||||
* // Object {1: Array[2], 2: Array[1], 3: Array[1], 4: Array[1]}
|
||||
*
|
||||
* _.groupBy([{ a: [1, 2, 3] }, { b: true, a: [1, 4] }], 'a')
|
||||
* // Object {'1,2,3': Array[1], '1,4': Array[1]}
|
||||
*
|
||||
* @param {array} collection - the list of values to organize
|
||||
* @param {Function} callback - either a property name, or a callback.
|
||||
* @return {object}
|
||||
*/
|
||||
export function organizeBy(collection, callback) {
|
||||
const buckets = {};
|
||||
const prop = typeof callback === 'function' ? false : callback;
|
||||
|
||||
function add(key, obj) {
|
||||
if (!buckets[key]) buckets[key] = [];
|
||||
buckets[key].push(obj);
|
||||
}
|
||||
|
||||
_.each(collection, function (obj) {
|
||||
const keys = prop === false ? callback(obj) : obj[prop];
|
||||
|
||||
if (!Array.isArray(keys)) {
|
||||
add(keys, obj);
|
||||
return;
|
||||
}
|
||||
|
||||
let length = keys.length;
|
||||
while (length-- > 0) {
|
||||
add(keys[length], obj);
|
||||
}
|
||||
});
|
||||
|
||||
return buckets;
|
||||
}
|
||||
|
||||
/**
|
||||
* Efficient and safe version of [].push(dest, source);
|
||||
*
|
||||
* @param {Array} source - the array to pull values from
|
||||
* @param {Array} dest - the array to push values into
|
||||
* @return {Array} dest
|
||||
*/
|
||||
export function pushAll(source, dest) {
|
||||
const start = dest.length;
|
||||
const adding = source.length;
|
||||
|
||||
// allocate - http://goo.gl/e2i0S0
|
||||
dest.length = start + adding;
|
||||
|
||||
// fill sparse positions
|
||||
let i = -1;
|
||||
while (++i < adding) dest[start + i] = source[i];
|
||||
|
||||
return dest;
|
||||
}
|
13
src/ui/public/utils/function.js
Normal file
13
src/ui/public/utils/function.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
import _ from 'lodash';
|
||||
|
||||
/**
|
||||
* Call all of the function in an array
|
||||
*
|
||||
* @param {array[functions]} arr
|
||||
* @return {undefined}
|
||||
*/
|
||||
export function callEach(arr) {
|
||||
return _.map(arr, function (fn) {
|
||||
return _.isFunction(fn) ? fn() : undefined;
|
||||
});
|
||||
}
|
38
src/ui/public/utils/legacy_class.js
Normal file
38
src/ui/public/utils/legacy_class.js
Normal file
|
@ -0,0 +1,38 @@
|
|||
// create a property descriptor for properties
|
||||
// that won't change
|
||||
function describeConst(val) {
|
||||
return {
|
||||
writable: false,
|
||||
enumerable: false,
|
||||
configurable: false,
|
||||
value: val
|
||||
};
|
||||
}
|
||||
|
||||
const props = {
|
||||
inherits: describeConst(function (SuperClass) {
|
||||
|
||||
const prototype = Object.create(SuperClass.prototype, {
|
||||
constructor: describeConst(this),
|
||||
superConstructor: describeConst(SuperClass)
|
||||
});
|
||||
|
||||
Object.defineProperties(this, {
|
||||
prototype: describeConst(prototype),
|
||||
Super: describeConst(SuperClass)
|
||||
});
|
||||
|
||||
return this;
|
||||
})
|
||||
};
|
||||
|
||||
/**
|
||||
* Add class-related behavior to a function, currently this
|
||||
* only attaches an .inherits() method.
|
||||
*
|
||||
* @param {Constructor} ClassConstructor - The function that should be extended
|
||||
* @return {Constructor} - the constructor passed in;
|
||||
*/
|
||||
export function createLegacyClass(ClassConstructor) {
|
||||
return Object.defineProperties(ClassConstructor, props);
|
||||
}
|
|
@ -1,162 +0,0 @@
|
|||
import _ from 'lodash';
|
||||
import expect from 'expect.js';
|
||||
describe('_.move', function () {
|
||||
|
||||
it('accepts previous from->to syntax', function () {
|
||||
const list = [
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
8,
|
||||
1,
|
||||
1,
|
||||
];
|
||||
|
||||
expect(list[3]).to.be(1);
|
||||
expect(list[8]).to.be(8);
|
||||
|
||||
_.move(list, 8, 3);
|
||||
|
||||
expect(list[8]).to.be(1);
|
||||
expect(list[3]).to.be(8);
|
||||
});
|
||||
|
||||
it('moves an object up based on a function callback', function () {
|
||||
const list = [
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
];
|
||||
|
||||
expect(list[4]).to.be(0);
|
||||
expect(list[5]).to.be(1);
|
||||
expect(list[6]).to.be(0);
|
||||
|
||||
_.move(list, 5, false, function (v) {
|
||||
return v === 0;
|
||||
});
|
||||
|
||||
expect(list[4]).to.be(1);
|
||||
expect(list[5]).to.be(0);
|
||||
expect(list[6]).to.be(0);
|
||||
});
|
||||
|
||||
it('moves an object down based on a function callback', function () {
|
||||
const list = [
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
];
|
||||
|
||||
expect(list[4]).to.be(0);
|
||||
expect(list[5]).to.be(1);
|
||||
expect(list[6]).to.be(0);
|
||||
|
||||
_.move(list, 5, true, function (v) {
|
||||
return v === 0;
|
||||
});
|
||||
|
||||
expect(list[4]).to.be(0);
|
||||
expect(list[5]).to.be(0);
|
||||
expect(list[6]).to.be(1);
|
||||
});
|
||||
|
||||
it('moves an object up based on a where callback', function () {
|
||||
const list = [
|
||||
{ v: 1 },
|
||||
{ v: 1 },
|
||||
{ v: 1 },
|
||||
{ v: 1 },
|
||||
{ v: 0 },
|
||||
{ v: 1 },
|
||||
{ v: 0 },
|
||||
{ v: 1 },
|
||||
{ v: 1 },
|
||||
{ v: 1 },
|
||||
{ v: 1 },
|
||||
];
|
||||
|
||||
expect(list[4]).to.have.property('v', 0);
|
||||
expect(list[5]).to.have.property('v', 1);
|
||||
expect(list[6]).to.have.property('v', 0);
|
||||
|
||||
_.move(list, 5, false, { v: 0 });
|
||||
|
||||
expect(list[4]).to.have.property('v', 1);
|
||||
expect(list[5]).to.have.property('v', 0);
|
||||
expect(list[6]).to.have.property('v', 0);
|
||||
});
|
||||
|
||||
|
||||
it('moves an object down based on a where callback', function () {
|
||||
const list = [
|
||||
{ v: 1 },
|
||||
{ v: 1 },
|
||||
{ v: 1 },
|
||||
{ v: 1 },
|
||||
{ v: 0 },
|
||||
{ v: 1 },
|
||||
{ v: 0 },
|
||||
{ v: 1 },
|
||||
{ v: 1 },
|
||||
{ v: 1 },
|
||||
{ v: 1 },
|
||||
];
|
||||
|
||||
expect(list[4]).to.have.property('v', 0);
|
||||
expect(list[5]).to.have.property('v', 1);
|
||||
expect(list[6]).to.have.property('v', 0);
|
||||
|
||||
_.move(list, 5, true, { v: 0 });
|
||||
|
||||
expect(list[4]).to.have.property('v', 0);
|
||||
expect(list[5]).to.have.property('v', 0);
|
||||
expect(list[6]).to.have.property('v', 1);
|
||||
});
|
||||
|
||||
it('moves an object down based on a pluck callback', function () {
|
||||
const list = [
|
||||
{ id: 0, normal: true },
|
||||
{ id: 1, normal: true },
|
||||
{ id: 2, normal: true },
|
||||
{ id: 3, normal: true },
|
||||
{ id: 4, normal: true },
|
||||
{ id: 5, normal: false },
|
||||
{ id: 6, normal: true },
|
||||
{ id: 7, normal: true },
|
||||
{ id: 8, normal: true },
|
||||
{ id: 9, normal: true }
|
||||
];
|
||||
|
||||
expect(list[4]).to.have.property('id', 4);
|
||||
expect(list[5]).to.have.property('id', 5);
|
||||
expect(list[6]).to.have.property('id', 6);
|
||||
|
||||
_.move(list, 5, true, 'normal');
|
||||
|
||||
expect(list[4]).to.have.property('id', 4);
|
||||
expect(list[5]).to.have.property('id', 6);
|
||||
expect(list[6]).to.have.property('id', 5);
|
||||
});
|
||||
});
|
|
@ -1,48 +0,0 @@
|
|||
import _ from 'lodash';
|
||||
import expect from 'expect.js';
|
||||
describe('_.organize', function () {
|
||||
|
||||
it('it works', function () {
|
||||
const col = [
|
||||
{
|
||||
name: 'one',
|
||||
roles: ['user', 'admin', 'owner']
|
||||
},
|
||||
{
|
||||
name: 'two',
|
||||
roles: ['user']
|
||||
},
|
||||
{
|
||||
name: 'three',
|
||||
roles: ['user']
|
||||
},
|
||||
{
|
||||
name: 'four',
|
||||
roles: ['user', 'admin']
|
||||
}
|
||||
];
|
||||
|
||||
const resp = _.organizeBy(col, 'roles');
|
||||
expect(resp).to.have.property('user');
|
||||
expect(resp.user).to.have.length(4);
|
||||
|
||||
expect(resp).to.have.property('admin');
|
||||
expect(resp.admin).to.have.length(2);
|
||||
|
||||
expect(resp).to.have.property('owner');
|
||||
expect(resp.owner).to.have.length(1);
|
||||
});
|
||||
|
||||
it('behaves just like groupBy in normal scenarios', function () {
|
||||
const col = [
|
||||
{ name: 'one' },
|
||||
{ name: 'two' },
|
||||
{ name: 'three' },
|
||||
{ name: 'four' }
|
||||
];
|
||||
|
||||
const orgs = _.organizeBy(col, 'name');
|
||||
const groups = _.groupBy(col, 'name');
|
||||
expect(orgs).to.eql(groups);
|
||||
});
|
||||
});
|
|
@ -1,14 +0,0 @@
|
|||
import _ from 'lodash';
|
||||
import expect from 'expect.js';
|
||||
describe('_.pushAll', function () {
|
||||
|
||||
it('pushes an entire array into another', function () {
|
||||
const a = [1, 2, 3, 4];
|
||||
const b = [5, 6, 7, 8];
|
||||
|
||||
const output = _.pushAll(b, a);
|
||||
expect(output).to.be(a);
|
||||
expect(a).to.eql([1, 2, 3, 4, 5, 6, 7, 8]);
|
||||
expect(b).to.eql([5, 6, 7, 8]);
|
||||
});
|
||||
});
|
|
@ -1,6 +0,0 @@
|
|||
import './_move';
|
||||
import './_organize_by';
|
||||
import './_push_all';
|
||||
|
||||
describe('lodash mixins', function () {
|
||||
});
|
|
@ -1,126 +0,0 @@
|
|||
export function lodashCollectionMixin(_) {
|
||||
_.mixin(_, {
|
||||
|
||||
/**
|
||||
* move an obj either up or down in the collection by
|
||||
* injecting it either before/after the prev/next obj that
|
||||
* satisfied the qualifier
|
||||
*
|
||||
* or, just from one index to another...
|
||||
*
|
||||
* @param {array} objs - the list to move the object within
|
||||
* @param {number|any} obj - the object that should be moved, or the index that the object is currently at
|
||||
* @param {number|boolean} below - the index to move the object to, or whether it should be moved up or down
|
||||
* @param {function} qualifier - a lodash-y callback, object = _.where, string = _.pluck
|
||||
* @return {array} - the objs argument
|
||||
*/
|
||||
move: function (objs, obj, below, qualifier) {
|
||||
const origI = _.isNumber(obj) ? obj : objs.indexOf(obj);
|
||||
if (origI === -1) return objs;
|
||||
|
||||
if (_.isNumber(below)) {
|
||||
// move to a specific index
|
||||
objs.splice(below, 0, objs.splice(origI, 1)[0]);
|
||||
return objs;
|
||||
}
|
||||
|
||||
below = !!below;
|
||||
qualifier = _.callback(qualifier);
|
||||
|
||||
const above = !below;
|
||||
const finder = below ? _.findIndex : _.findLastIndex;
|
||||
|
||||
// find the index of the next/previous obj that meets the qualifications
|
||||
const targetI = finder(objs, function (otherAgg, otherI) {
|
||||
if (below && otherI <= origI) return;
|
||||
if (above && otherI >= origI) return;
|
||||
return !!qualifier(otherAgg, otherI);
|
||||
});
|
||||
|
||||
if (targetI === -1) return objs;
|
||||
|
||||
// place the obj at it's new index
|
||||
objs.splice(targetI, 0, objs.splice(origI, 1)[0]);
|
||||
},
|
||||
|
||||
/**
|
||||
* Like _.groupBy, but allows specifying multiple groups for a
|
||||
* single object.
|
||||
*
|
||||
* _.organizeBy([{ a: [1, 2, 3] }, { b: true, a: [1, 4] }], 'a')
|
||||
* // Object {1: Array[2], 2: Array[1], 3: Array[1], 4: Array[1]}
|
||||
*
|
||||
* _.groupBy([{ a: [1, 2, 3] }, { b: true, a: [1, 4] }], 'a')
|
||||
* // Object {'1,2,3': Array[1], '1,4': Array[1]}
|
||||
*
|
||||
* @param {array} collection - the list of values to organize
|
||||
* @param {Function} callback - either a property name, or a callback.
|
||||
* @return {object}
|
||||
*/
|
||||
organizeBy: function (collection, callback) {
|
||||
const buckets = {};
|
||||
const prop = typeof callback === 'function' ? false : callback;
|
||||
|
||||
function add(key, obj) {
|
||||
if (!buckets[key]) buckets[key] = [];
|
||||
buckets[key].push(obj);
|
||||
}
|
||||
|
||||
_.each(collection, function (obj) {
|
||||
const keys = prop === false ? callback(obj) : obj[prop];
|
||||
|
||||
if (!Array.isArray(keys)) {
|
||||
add(keys, obj);
|
||||
return;
|
||||
}
|
||||
|
||||
let length = keys.length;
|
||||
while (length-- > 0) {
|
||||
add(keys[length], obj);
|
||||
}
|
||||
});
|
||||
|
||||
return buckets;
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove or add a value to an array based on it's presense in the
|
||||
* array initially.
|
||||
*
|
||||
* @param {array} arr
|
||||
* @param {any} value - the value to toggle
|
||||
* @return {array} arr
|
||||
*/
|
||||
toggleInOut: function (arr, value) {
|
||||
if (_.contains(arr, value)) {
|
||||
arr.splice(arr.indexOf(value), 1);
|
||||
} else {
|
||||
arr.push(value);
|
||||
}
|
||||
return arr;
|
||||
},
|
||||
|
||||
/**
|
||||
* Efficient and safe version of [].push(dest, source);
|
||||
*
|
||||
* @param {Array} source - the array to pull values from
|
||||
* @param {Array} dest - the array to push values into
|
||||
* @return {Array} dest
|
||||
*/
|
||||
pushAll: function (source, dest) {
|
||||
const start = dest.length;
|
||||
const adding = source.length;
|
||||
|
||||
// allocate - http://goo.gl/e2i0S0
|
||||
dest.length = start + adding;
|
||||
|
||||
// fill sparse positions
|
||||
let i = -1;
|
||||
while (++i < adding) dest[start + i] = source[i];
|
||||
|
||||
return dest;
|
||||
},
|
||||
|
||||
|
||||
});
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
export function lodashFunctionMixin(_) {
|
||||
_.mixin({
|
||||
|
||||
/**
|
||||
* Create a method that wraps another method which expects a callback as it's last
|
||||
* argument. The wrapper method will call the wrapped function only once (the first
|
||||
* time it is called), but will always call the callbacks passed to it. This has a
|
||||
* similar effect to calling a promise-returning function that is wrapped with _.once
|
||||
* but can be used outside of angular.
|
||||
*
|
||||
* @param {Function} fn - the function that should only be executed once and accepts
|
||||
* a callback as it's last arg
|
||||
* @return {Function} - the wrapper method
|
||||
*/
|
||||
onceWithCb: function (fn) {
|
||||
const callbacks = [];
|
||||
|
||||
// on initial flush, call the init function, but ensure
|
||||
// that it only happens once
|
||||
let flush = _.once(function (cntx, args) {
|
||||
args.push(function finishedOnce() {
|
||||
// override flush to simply schedule an asynchronous clear
|
||||
flush = function () {
|
||||
setTimeout(function () {
|
||||
_.callEach(callbacks.splice(0));
|
||||
}, 0);
|
||||
};
|
||||
|
||||
flush();
|
||||
});
|
||||
|
||||
fn.apply(cntx, args);
|
||||
});
|
||||
|
||||
return function runOnceWithCb() {
|
||||
let args = [].slice.call(arguments, 0);
|
||||
const cb = args[args.length - 1];
|
||||
|
||||
if (typeof cb === 'function') {
|
||||
callbacks.push(cb);
|
||||
// trim the arg list so the other callback can
|
||||
// be pushed if needed
|
||||
args = args.slice(0, -1);
|
||||
}
|
||||
|
||||
// always call flush, it might not do anything
|
||||
flush(this, args);
|
||||
};
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Call all of the function in an array
|
||||
*
|
||||
* @param {array[functions]} arr
|
||||
* @return {undefined}
|
||||
*/
|
||||
callEach: function (arr) {
|
||||
return _.map(arr, function (fn) {
|
||||
return _.isFunction(fn) ? fn() : undefined;
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
export function lodashLangMixin(_) {
|
||||
_.mixin(_, {
|
||||
|
||||
|
||||
/**
|
||||
* Checks to see if an input value is number-like, this
|
||||
* includes strings that parse into valid numbers and objects
|
||||
* that don't have a type of number but still parse properly
|
||||
* via-some sort of valueOf magic
|
||||
*
|
||||
* @param {any} v - the value to check
|
||||
* @return {Boolean}
|
||||
*/
|
||||
isNumeric: function (v) {
|
||||
return !_.isNaN(v) && (typeof v === 'number' || (!Array.isArray(v) && !_.isNaN(parseFloat(v))));
|
||||
},
|
||||
|
||||
});
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
export function lodashObjectMixin(_) {
|
||||
return _.mixin(_, {
|
||||
|
||||
/**
|
||||
* Flatten an object into a single-level object.
|
||||
* NOTE: The flatten behavior here works if you don't need to keep a reference to the original value
|
||||
*
|
||||
* set flattenArrays to traverse into arrays and create properties like:
|
||||
* {
|
||||
* 'users.0.name': 'username1',
|
||||
* 'users.1.name': 'username2',
|
||||
* 'users.2.name': 'username3',
|
||||
* }
|
||||
*
|
||||
* @param {string} dot - the seperator for keys, '.' is generally preferred
|
||||
* @param {object} nestedObj - the object to flatten
|
||||
* @param {Boolean} flattenArrays - should arrays be travered or left alone?
|
||||
* @return {object}
|
||||
*/
|
||||
flattenWith: function (dot, nestedObj, flattenArrays) {
|
||||
const stack = []; // track key stack
|
||||
const flatObj = {};
|
||||
|
||||
(function flattenObj(obj) {
|
||||
_.keys(obj).forEach(function (key) {
|
||||
stack.push(key);
|
||||
if (!flattenArrays && Array.isArray(obj[key])) flatObj[stack.join(dot)] = obj[key];
|
||||
else if (_.isObject(obj[key])) flattenObj(obj[key]);
|
||||
else flatObj[stack.join(dot)] = obj[key];
|
||||
stack.pop();
|
||||
});
|
||||
}(nestedObj));
|
||||
|
||||
return flatObj;
|
||||
}
|
||||
|
||||
});
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
export function lodashOopMixin(_) {
|
||||
|
||||
// create a property descriptor for properties
|
||||
// that won't change
|
||||
function describeConst(val) {
|
||||
return {
|
||||
writable: false,
|
||||
enumerable: false,
|
||||
configurable: false,
|
||||
value: val
|
||||
};
|
||||
}
|
||||
|
||||
const props = {
|
||||
inherits: describeConst(function (SuperClass) {
|
||||
|
||||
const prototype = Object.create(SuperClass.prototype, {
|
||||
constructor: describeConst(this),
|
||||
superConstructor: describeConst(SuperClass)
|
||||
});
|
||||
|
||||
Object.defineProperties(this, {
|
||||
prototype: describeConst(prototype),
|
||||
Super: describeConst(SuperClass)
|
||||
});
|
||||
|
||||
return this;
|
||||
})
|
||||
};
|
||||
|
||||
_.mixin(_, {
|
||||
|
||||
/**
|
||||
* Add class-related behavior to a function, currently this
|
||||
* only attaches an .inherits() method.
|
||||
*
|
||||
* @param {Constructor} ClassConstructor - The function that should be extended
|
||||
* @return {Constructor} - the constructor passed in;
|
||||
*/
|
||||
class: function (ClassConstructor) {
|
||||
return Object.defineProperties(ClassConstructor, props);
|
||||
}
|
||||
});
|
||||
}
|
5
src/ui/public/utils/numeric.js
Normal file
5
src/ui/public/utils/numeric.js
Normal file
|
@ -0,0 +1,5 @@
|
|||
import _ from 'lodash';
|
||||
|
||||
export function isNumeric(v) {
|
||||
return !_.isNaN(v) && (typeof v === 'number' || (!Array.isArray(v) && !_.isNaN(parseFloat(v))));
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
import _ from 'lodash';
|
||||
import { BaseObject } from 'ui/utils/base_object';
|
||||
import { createLegacyClass } from './legacy_class';
|
||||
|
||||
/**
|
||||
* Simple event emitter class used in the vislib. Calls
|
||||
|
@ -7,7 +8,7 @@ import { BaseObject } from 'ui/utils/base_object';
|
|||
*
|
||||
* @class
|
||||
*/
|
||||
_.class(SimpleEmitter).inherits(BaseObject);
|
||||
createLegacyClass(SimpleEmitter).inherits(BaseObject);
|
||||
export function SimpleEmitter() {
|
||||
this._listeners = {};
|
||||
}
|
||||
|
|
|
@ -11,11 +11,12 @@ import _ from 'lodash';
|
|||
import { IndexedArray } from 'ui/indexed_array';
|
||||
import { AggConfig } from 'ui/vis/agg_config';
|
||||
import { AggTypesIndexProvider } from 'ui/agg_types/index';
|
||||
import { createLegacyClass } from '../utils/legacy_class';
|
||||
|
||||
export function VisAggConfigsProvider(Private) {
|
||||
AggConfig.aggTypes = Private(AggTypesIndexProvider);
|
||||
|
||||
_.class(AggConfigs).inherits(IndexedArray);
|
||||
createLegacyClass(AggConfigs).inherits(IndexedArray);
|
||||
function AggConfigs(vis, configStates) {
|
||||
const self = this;
|
||||
self.vis = vis;
|
||||
|
|
|
@ -4,6 +4,8 @@ import { Direction } from './keyboard_move';
|
|||
import _ from 'lodash';
|
||||
import { uiModules } from 'ui/modules';
|
||||
import aggTemplate from './agg.html';
|
||||
import { move } from '../../../utils/collection';
|
||||
|
||||
uiModules
|
||||
.get('app/visualize')
|
||||
.directive('visEditorAgg', function ($compile, $parse, $filter, Private, Notifier) {
|
||||
|
@ -60,7 +62,7 @@ uiModules
|
|||
|
||||
const currentPosition = $scope.group.indexOf($scope.agg);
|
||||
const newPosition = Math.max(0, Math.min(currentPosition + positionOffset, $scope.group.length - 1));
|
||||
_.move($scope.group, currentPosition, newPosition);
|
||||
move($scope.group, currentPosition, newPosition);
|
||||
$scope.$emit('agg-reorder');
|
||||
};
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import './nesting_indicator';
|
|||
|
||||
import { uiModules } from 'ui/modules';
|
||||
import aggGroupTemplate from './agg_group.html';
|
||||
import { move } from '../../../utils/collection';
|
||||
|
||||
uiModules
|
||||
.get('app/visualize')
|
||||
|
@ -48,7 +49,7 @@ uiModules
|
|||
//to apply that ordering to [vis.aggs]
|
||||
const indexOffset = $scope.vis.aggs.indexOf($scope.group[0]);
|
||||
_.forEach($scope.group, (agg, index) => {
|
||||
_.move($scope.vis.aggs, agg, indexOffset + index);
|
||||
move($scope.vis.aggs, agg, indexOffset + index);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import _ from 'lodash';
|
||||
import { uiModules } from 'ui/modules';
|
||||
import { callEach } from '../utils/function';
|
||||
|
||||
uiModules.get('kibana')
|
||||
.config(function ($provide) {
|
||||
|
@ -80,7 +81,7 @@ uiModules.get('kibana')
|
|||
});
|
||||
}));
|
||||
|
||||
return _.partial(_.callEach, unwatchers);
|
||||
return _.partial(callEach, unwatchers);
|
||||
};
|
||||
|
||||
function normalizeExpression($scope, expr) {
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
/**
|
||||
* THESE ARE AUTOMATICALLY INCLUDED IN LODASH
|
||||
*
|
||||
* use:
|
||||
* var _ = require('lodash');
|
||||
*/
|
||||
|
||||
var _ = require('../node_modules/lodash/index.js').runInContext();
|
||||
var lodashLangMixin = require('ui/utils/lodash-mixins/lang').lodashLangMixin;
|
||||
var lodashObjectMixin = require('ui/utils/lodash-mixins/object').lodashObjectMixin;
|
||||
var lodashCollectionMixin = require('ui/utils/lodash-mixins/collection').lodashCollectionMixin;
|
||||
var lodashFunctionMixin = require('ui/utils/lodash-mixins/function').lodashFunctionMixin;
|
||||
var lodashOopMixin = require('ui/utils/lodash-mixins/oop').lodashOopMixin;
|
||||
|
||||
lodashLangMixin(_);
|
||||
lodashObjectMixin(_);
|
||||
lodashCollectionMixin(_);
|
||||
lodashFunctionMixin(_);
|
||||
lodashOopMixin(_);
|
||||
|
||||
module.exports = _;
|
Loading…
Add table
Add a link
Reference in a new issue