Skip to content

Commit

Permalink
removing angular from AggConfigs
Browse files Browse the repository at this point in the history
  • Loading branch information
ppisljar committed Apr 17, 2018
1 parent 4577138 commit b6d2b05
Show file tree
Hide file tree
Showing 4 changed files with 166 additions and 173 deletions.
4 changes: 1 addition & 3 deletions src/ui/public/vis/__tests__/_agg_configs.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,18 @@ import expect from 'expect.js';
import ngMock from 'ng_mock';
import { AggConfig } from 'ui/vis/agg_config';
import { VisProvider } from 'ui/vis';
import { VisAggConfigsProvider } from 'ui/vis/agg_configs';
import { AggConfigs } from 'ui/vis/agg_configs';
import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern';
import { Schemas } from 'ui/vis/editors/default/schemas';
import { IndexedArray } from 'ui/indexed_array';

describe('AggConfigs', function () {

let Vis;
let AggConfigs;
let indexPattern;

beforeEach(ngMock.module('kibana'));
beforeEach(ngMock.inject(function (Private) {
AggConfigs = Private(VisAggConfigsProvider);
// replace the AggConfig module with a spy

const spy = sinon.spy(AggConfig);
Expand Down
3 changes: 2 additions & 1 deletion src/ui/public/vis/agg_config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import _ from 'lodash';
import { fieldFormats } from 'ui/registry/field_formats';

import { aggTypes } from 'ui/agg_types/index';

function AggConfig(vis, opts) {
const self = this;
Expand All @@ -29,6 +29,7 @@ function AggConfig(vis, opts) {
self.setParams(opts.params || {});
}

AggConfig.aggTypes = aggTypes;
/**
* Ensure that all of the objects in the list have ids, the objects
* and list are modified by reference.
Expand Down
329 changes: 162 additions & 167 deletions src/ui/public/vis/agg_configs.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,188 +10,183 @@
import _ from 'lodash';
import { IndexedArray } from 'ui/indexed_array';
import { AggConfig } from 'ui/vis/agg_config';
import { aggTypes } from 'ui/agg_types/index';

export function VisAggConfigsProvider() {
AggConfig.aggTypes = aggTypes;

_.class(AggConfigs).inherits(IndexedArray);
function AggConfigs(vis, configStates) {
const self = this;
self.vis = vis;

configStates = AggConfig.ensureIds(configStates || []);

AggConfigs.Super.call(self, {
index: ['id'],
group: ['schema.group', 'type.name', 'schema.name'],
initialSet: configStates.map(function (aggConfigState) {
if (aggConfigState instanceof AggConfig) return aggConfigState;
return new AggConfig(vis, aggConfigState);
_.class(AggConfigs).inherits(IndexedArray);
function AggConfigs(vis, configStates) {
const self = this;
self.vis = vis;

configStates = AggConfig.ensureIds(configStates || []);

AggConfigs.Super.call(self, {
index: ['id'],
group: ['schema.group', 'type.name', 'schema.name'],
initialSet: configStates.map(function (aggConfigState) {
if (aggConfigState instanceof AggConfig) return aggConfigState;
return new AggConfig(vis, aggConfigState);
})
});


// Set the defaults for any schema which has them. If the defaults
// for some reason has more then the max only set the max number
// of defaults (not sure why a someone define more...
// but whatever). Also if a schema.name is already set then don't
// set anything.
if (vis && vis.type && vis.type.schemas && vis.type.schemas.all) {
_(vis.type.schemas.all)
.filter(function (schema) {
return Array.isArray(schema.defaults) && schema.defaults.length > 0;
})
});


// Set the defaults for any schema which has them. If the defaults
// for some reason has more then the max only set the max number
// of defaults (not sure why a someone define more...
// but whatever). Also if a schema.name is already set then don't
// set anything.
if (vis && vis.type && vis.type.schemas && vis.type.schemas.all) {
_(vis.type.schemas.all)
.filter(function (schema) {
return Array.isArray(schema.defaults) && schema.defaults.length > 0;
})
.each(function (schema) {
if (!self.bySchemaName[schema.name]) {
const defaults = schema.defaults.slice(0, schema.max);
_.each(defaults, function (defaultState) {
const state = _.defaults({ id: AggConfig.nextId(self) }, defaultState);
self.push(new AggConfig(vis, state));
});
}
})
.commit();
}
.each(function (schema) {
if (!self.bySchemaName[schema.name]) {
const defaults = schema.defaults.slice(0, schema.max);
_.each(defaults, function (defaultState) {
const state = _.defaults({ id: AggConfig.nextId(self) }, defaultState);
self.push(new AggConfig(vis, state));
});
}
})
.commit();
}
}

/**
* Data-by-data comparison of this Aggregation
* Ignores the non-array indexes
* @param aggConfigs an AggConfigs instance
*/
AggConfigs.prototype.jsonDataEquals = function (aggConfigs) {
if (aggConfigs.length !== this.length) {
/**
* Data-by-data comparison of this Aggregation
* Ignores the non-array indexes
* @param aggConfigs an AggConfigs instance
*/
AggConfigs.prototype.jsonDataEquals = function (aggConfigs) {
if (aggConfigs.length !== this.length) {
return false;
}
for (let i = 0; i < this.length; i += 1) {
if (!_.isEqual(aggConfigs[i].toJSON(), this[i].toJSON())) {
return false;
}
for (let i = 0; i < this.length; i += 1) {
if (!_.isEqual(aggConfigs[i].toJSON(), this[i].toJSON())) {
return false;
}
}
return true;
};
}
return true;
};

function removeParentAggs(obj) {
for(const prop in obj) {
if (prop === 'parentAggs') delete obj[prop];
else if (typeof obj[prop] === 'object') removeParentAggs(obj[prop]);
}
function removeParentAggs(obj) {
for(const prop in obj) {
if (prop === 'parentAggs') delete obj[prop];
else if (typeof obj[prop] === 'object') removeParentAggs(obj[prop]);
}
}

function parseParentAggs(dslLvlCursor, dsl) {
if (dsl.parentAggs) {
_.each(dsl.parentAggs, (agg, key) => {
dslLvlCursor[key] = agg;
parseParentAggs(dslLvlCursor, agg);
});
}
function parseParentAggs(dslLvlCursor, dsl) {
if (dsl.parentAggs) {
_.each(dsl.parentAggs, (agg, key) => {
dslLvlCursor[key] = agg;
parseParentAggs(dslLvlCursor, agg);
});
}
}

AggConfigs.prototype.toDsl = function () {
const dslTopLvl = {};
let dslLvlCursor;
let nestedMetrics;

if (this.vis.isHierarchical()) {
// collect all metrics, and filter out the ones that we won't be copying
nestedMetrics = _(this.vis.aggs.bySchemaGroup.metrics)
.filter(function (agg) {
return agg.type.name !== 'count';
})
.map(function (agg) {
return {
config: agg,
dsl: agg.toDsl()
};
})
.value();
}
this.getRequestAggs()
.filter(function (config) {
return !config.type.hasNoDsl;
AggConfigs.prototype.toDsl = function () {
const dslTopLvl = {};
let dslLvlCursor;
let nestedMetrics;

if (this.vis.isHierarchical()) {
// collect all metrics, and filter out the ones that we won't be copying
nestedMetrics = _(this.vis.aggs.bySchemaGroup.metrics)
.filter(function (agg) {
return agg.type.name !== 'count';
})
.forEach(function nestEachConfig(config, i, list) {
if (!dslLvlCursor) {
// start at the top level
dslLvlCursor = dslTopLvl;
} else {
const prevConfig = list[i - 1];
const prevDsl = dslLvlCursor[prevConfig.id];

// advance the cursor and nest under the previous agg, or
// put it on the same level if the previous agg doesn't accept
// sub aggs
dslLvlCursor = prevDsl.aggs || dslLvlCursor;
}
.map(function (agg) {
return {
config: agg,
dsl: agg.toDsl()
};
})
.value();
}
this.getRequestAggs()
.filter(function (config) {
return !config.type.hasNoDsl;
})
.forEach(function nestEachConfig(config, i, list) {
if (!dslLvlCursor) {
// start at the top level
dslLvlCursor = dslTopLvl;
} else {
const prevConfig = list[i - 1];
const prevDsl = dslLvlCursor[prevConfig.id];

// advance the cursor and nest under the previous agg, or
// put it on the same level if the previous agg doesn't accept
// sub aggs
dslLvlCursor = prevDsl.aggs || dslLvlCursor;
}

const dsl = dslLvlCursor[config.id] = config.toDsl();
let subAggs;
const dsl = dslLvlCursor[config.id] = config.toDsl();
let subAggs;

parseParentAggs(dslLvlCursor, dsl);
parseParentAggs(dslLvlCursor, dsl);

if (config.schema.group === 'buckets' && i < list.length - 1) {
// buckets that are not the last item in the list accept sub-aggs
subAggs = dsl.aggs || (dsl.aggs = {});
}
if (config.schema.group === 'buckets' && i < list.length - 1) {
// buckets that are not the last item in the list accept sub-aggs
subAggs = dsl.aggs || (dsl.aggs = {});
}

if (subAggs && nestedMetrics) {
nestedMetrics.forEach(function (agg) {
subAggs[agg.config.id] = agg.dsl;
});
}
});

removeParentAggs(dslTopLvl);
return dslTopLvl;
};

AggConfigs.prototype.getRequestAggs = function () {
//collect all the aggregations
const aggregations = this.reduce((requestValuesAggs, agg) => {
const aggs = agg.getRequestAggs();
return aggs ? requestValuesAggs.concat(aggs) : requestValuesAggs;
}, []);
//move metrics to the end
return _.sortBy(aggregations, function (agg) {
return agg.schema.group === 'metrics' ? 1 : 0;
});
};

/**
* Gets the AggConfigs (and possibly ResponseAggConfigs) that
* represent the values that will be produced when all aggs
* are run.
*
* With multi-value metric aggs it is possible for a single agg
* request to result in multiple agg values, which is why the length
* of a vis' responseValuesAggs may be different than the vis' aggs
*
* @return {array[AggConfig]}
*/
AggConfigs.prototype.getResponseAggs = function () {
return this.getRequestAggs().reduce(function (responseValuesAggs, agg) {
const aggs = agg.getResponseAggs();
return aggs ? responseValuesAggs.concat(aggs) : responseValuesAggs;
}, []);
};


/**
* Find a response agg by it's id. This may be an agg in the aggConfigs, or one
* created specifically for a response value
*
* @param {string} id - the id of the agg to find
* @return {AggConfig}
*/
AggConfigs.prototype.getResponseAggById = function (id) {
id = String(id);
const reqAgg = _.find(this.getRequestAggs(), function (agg) {
return id.substr(0, String(agg.id).length) === agg.id;
if (subAggs && nestedMetrics) {
nestedMetrics.forEach(function (agg) {
subAggs[agg.config.id] = agg.dsl;
});
}
});
if (!reqAgg) return;
return _.find(reqAgg.getResponseAggs(), { id: id });
};

return AggConfigs;
}
removeParentAggs(dslTopLvl);
return dslTopLvl;
};

AggConfigs.prototype.getRequestAggs = function () {
//collect all the aggregations
const aggregations = this.reduce((requestValuesAggs, agg) => {
const aggs = agg.getRequestAggs();
return aggs ? requestValuesAggs.concat(aggs) : requestValuesAggs;
}, []);
//move metrics to the end
return _.sortBy(aggregations, function (agg) {
return agg.schema.group === 'metrics' ? 1 : 0;
});
};

/**
* Gets the AggConfigs (and possibly ResponseAggConfigs) that
* represent the values that will be produced when all aggs
* are run.
*
* With multi-value metric aggs it is possible for a single agg
* request to result in multiple agg values, which is why the length
* of a vis' responseValuesAggs may be different than the vis' aggs
*
* @return {array[AggConfig]}
*/
AggConfigs.prototype.getResponseAggs = function () {
return this.getRequestAggs().reduce(function (responseValuesAggs, agg) {
const aggs = agg.getResponseAggs();
return aggs ? responseValuesAggs.concat(aggs) : responseValuesAggs;
}, []);
};


/**
* Find a response agg by it's id. This may be an agg in the aggConfigs, or one
* created specifically for a response value
*
* @param {string} id - the id of the agg to find
* @return {AggConfig}
*/
AggConfigs.prototype.getResponseAggById = function (id) {
id = String(id);
const reqAgg = _.find(this.getRequestAggs(), function (agg) {
return id.substr(0, String(agg.id).length) === agg.id;
});
if (!reqAgg) return;
return _.find(reqAgg.getResponseAggs(), { id: id });
};

export { AggConfigs };
Loading

0 comments on commit b6d2b05

Please sign in to comment.