feat: Refactor to a filterable-store
This commit is contained in:
3 files changed
+101
No files matched your search
@@ -0,0 +1,68 @@
|
||||
import Store from '@ember-data/store';
|
||||
|
||||
class FilterQuery {
|
||||
_config;
|
||||
constructor(config) {
|
||||
this._config = config;
|
||||
}
|
||||
|
||||
get query() {
|
||||
const filters = this._buildFilters(this._config);
|
||||
return this._joinFilters(filters, { inclusive: false });
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterate through filter config to generate array of filter strings
|
||||
* @param {object} config
|
||||
*/
|
||||
_buildFilters(config) {
|
||||
let filters = [];
|
||||
for (const key in config) {
|
||||
filters.push(this._generateQuery(`/item/${key}`, config[`${key}`]));
|
||||
}
|
||||
return filters;
|
||||
}
|
||||
|
||||
/**
|
||||
* For a single filter, build filter query
|
||||
* @param {string} selector
|
||||
* @param {*} values
|
||||
*/
|
||||
_generateQuery(selector, values) {
|
||||
// TODO: Check for value type
|
||||
const filters = values.map((value) => `"${selector}" == "${value}"`);
|
||||
return this._joinFilters(filters, { inclusive: true });
|
||||
}
|
||||
|
||||
/**
|
||||
* Combine filter strings
|
||||
* @param {array} filters
|
||||
* @param {object} inclusive
|
||||
*/
|
||||
_joinFilters(filters, { inclusive }) {
|
||||
return filters.join(inclusive ? ' or ' : ' and ');
|
||||
}
|
||||
}
|
||||
export default class FilterableStoreService extends Store {
|
||||
/**
|
||||
* Filterable store queries using IDs
|
||||
* Usage:
|
||||
* // Filter for a user in sessions
|
||||
* this.store.filterByIds('session', { scope_id, recursive: true }, { user: ['u_0987654321']})
|
||||
* // Filter for status in pending or terminated state and for a session id
|
||||
* this.store.filterByIds('session', { scope_id },
|
||||
* { status: ['pending', 'terminated' ], target: ['s_U5EoFe4Jba']}
|
||||
* )
|
||||
* // To remove filters
|
||||
* this.store.filterByIds('session', { scope_id })
|
||||
* @param {string} modelName
|
||||
* @param {object} queryOptions
|
||||
* @param {string} filterQuery
|
||||
*/
|
||||
filterByIds(modelName, queryOptions, filterOptions) {
|
||||
const filterQuery = new FilterQuery(filterOptions);
|
||||
// Apply filters, if available
|
||||
if (filterQuery.query) queryOptions.filter = filterQuery;
|
||||
return this.query(modelName, queryOptions);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export { default } from 'api/services/filterable-store';
|
||||
@@ -0,0 +1,32 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
|
||||
module('Unit | Service | filterable-store', function (hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
let store;
|
||||
|
||||
hooks.beforeEach(function () {
|
||||
store = this.owner.lookup('service:filterable-store');
|
||||
|
||||
store.createRecord('account', {
|
||||
id: 'i_1234567890',
|
||||
scope: {
|
||||
id: '123',
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
test('it supports query filtering', function (assert) {
|
||||
tore.filterByIds('account', { scope_id: '123' });
|
||||
assert.ok(store);
|
||||
});
|
||||
|
||||
test('it supports single attribute filters', function (assert) {
|
||||
assert.ok(store);
|
||||
});
|
||||
|
||||
test('it supports multiple attribute filters', function (assert) {
|
||||
assert.ok(store);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user