[UI Registry] Filter out any empty items before registering them (#17027)

* Filter out any empty items

Registry providers expose a `register` method to allow registration of items into the registry. This method expects as its sole argument an "item registration" function that returns an object representing the item to be registered into the registry. The arguments to this function can be other providers, allowing for dynamic construction of the item object to be returned.

This change will filter out any empty item objects before they are added to the registry. This allows the item registration function to return a falsy value if it needs to decide, dynamically at runtime, not to register an item.

* Adding unit test

* Adding skipEmptyItems spec param

* Using skipEmptyItems spec param when creating FeatureCatalogueRegistry

* Using a more generic approach instead

Now the spec takes an optional `filter` function that can be defined as per the requirements of the specific registry rather than baking in logic for skipping items for all registries into ui/registry itself.

* Renaming var to be more descriptive
This commit is contained in:
Shaunak Kashyap 2018-03-08 20:12:56 -08:00
parent 3e5a220740
commit 4f2b0fb518
3 changed files with 25 additions and 1 deletions

View file

@ -23,6 +23,20 @@ describe('Registry', function () {
reg.register(mod);
// modules are not exposed, so this is the most that we can test
});
it('applies the filter function if one is specified', function () {
const reg = uiRegistry({
filter: item => item.value % 2 === 0 // register only even numbers
});
reg.register(() => ({ value: 17 }));
reg.register(() => ({ value: 18 })); // only this one should get registered
reg.register(() => ({ value: 19 }));
const modules = Private(reg);
expect(modules).to.have.length(1);
expect(modules[0].value).to.be(18);
});
});
describe('as a module', function () {

View file

@ -35,6 +35,10 @@ const notPropsOptNames = IndexedArray.OPT_NAMES.concat('constructor', 'invokePro
* # init
* @param {Function} [spec.constructor] - an injectable function that is called when
* the registry is first instanciated by the app.
* @param {boolean} [spec.filter] - function that will be used to filter items before
* registering them. Function will called on each item and
* should return true to keep the item (register it) or
* skip it (don't register it)
*
* # IndexedArray params
* @param {array[String]} [spec.index] - passed to the IndexedArray constructor
@ -49,6 +53,7 @@ export function uiRegistry(spec) {
spec = spec || {};
const constructor = _.has(spec, 'constructor') && spec.constructor;
const filter = _.has(spec, 'filter') && spec.filter;
const invokeProviders = _.has(spec, 'invokeProviders') && spec.invokeProviders;
const iaOpts = _.defaults(_.pick(spec, IndexedArray.OPT_NAMES), { index: ['name'] });
const props = _.omit(spec, notPropsOptNames);
@ -68,6 +73,10 @@ export function uiRegistry(spec) {
? $injector.invoke(invokeProviders, undefined, { providers })
: providers.map(Private);
if (filter && _.isFunction(filter)) {
iaOpts.initialSet = iaOpts.initialSet.filter(item => filter(item));
}
// index all of the modules
let modules = new IndexedArray(iaOpts);

View file

@ -4,7 +4,8 @@ export const FeatureCatalogueRegistryProvider = uiRegistry({
name: 'featureCatalogue',
index: ['id'],
group: ['category'],
order: ['title']
order: ['title'],
filter: featureCatalogItem => Object.keys(featureCatalogItem).length > 0
});
export const FeatureCatalogueCategory = {