Merge branch 'main' into feature-list-managed-groups
This commit is contained in:
4 files changed
+130
-2
No files matched your search
@@ -0,0 +1,109 @@
|
||||
import Service from '@ember/service';
|
||||
import { inject as service } from '@ember/service';
|
||||
|
||||
/**
|
||||
* Takes a POJO representing a query and converts it to a boolean expression
|
||||
* string which is understood by the API.
|
||||
*
|
||||
* @example
|
||||
* const filter = new ResourceFilter({
|
||||
* type: 'oidc',
|
||||
* status: ['active', 'pending']
|
||||
* });
|
||||
* console.log(filter.queryExpression);
|
||||
* // ("/item/type" == "oidc") and ("/item/status" == "active" or "/item/status" == "pending")
|
||||
*/
|
||||
export class ResourceFilter {
|
||||
// =attributes
|
||||
|
||||
/**
|
||||
* @type {?object}
|
||||
*/
|
||||
#filterObject;
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
*/
|
||||
get queryExpression() {
|
||||
const clauses = Object.keys(this.#filterObject)
|
||||
.map((key) => {
|
||||
const value = this.#filterObject[key];
|
||||
const valuesArray = Array.isArray(value) ? value : [value];
|
||||
return this.parenthetical(
|
||||
this.or(valuesArray.map((value) => this.equals(key, value)))
|
||||
);
|
||||
})
|
||||
.flat();
|
||||
return this.and(clauses);
|
||||
}
|
||||
|
||||
// =methods
|
||||
|
||||
/**
|
||||
* @param {object} filterObject
|
||||
*/
|
||||
constructor(filterObject = {}) {
|
||||
this.#filterObject = Object.assign({}, filterObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} key
|
||||
* @param value
|
||||
* @return {string}
|
||||
*/
|
||||
equals(key, value) {
|
||||
return `"/item/${key}" == "${value}"`;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string[]} clauses
|
||||
* @return {string}
|
||||
*/
|
||||
and(clauses) {
|
||||
return clauses.join(' and ');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string[]} clauses
|
||||
* @return {string}
|
||||
*/
|
||||
or(clauses) {
|
||||
return clauses.join(' or ');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} expression
|
||||
* @return {string}
|
||||
*/
|
||||
parenthetical(expression) {
|
||||
return `(${expression})`;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export default class ResourceFilterStoreService extends Service {
|
||||
// =services
|
||||
|
||||
@service store;
|
||||
|
||||
// =methods
|
||||
|
||||
/**
|
||||
* Similar to Ember's built-in `store.query`, except this method accepts
|
||||
* an additional argument `filterObject` representing a query filter
|
||||
* (see ResourceFilter class above).
|
||||
* @param {string} modelName
|
||||
* @param {object} filterObject
|
||||
* @param {?object} storeQuery
|
||||
* @return {Promise}
|
||||
*/
|
||||
queryBy(modelName, filterObject = {}, storeQuery = {}) {
|
||||
const filter = new ResourceFilter(filterObject);
|
||||
const query = Object.assign({}, storeQuery);
|
||||
// Apply filters to store query when available
|
||||
if (filter.queryExpression) query.filter = filter.queryExpression;
|
||||
return this.store.query(modelName, query);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export { default } from 'api/services/resource-filter-store';
|
||||
@@ -0,0 +1,18 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
import { ResourceFilter } from 'api/services/resource-filter-store';
|
||||
|
||||
module('Unit | Service | resource-filter-store', function (hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
test('it exports a ResourceFilter class that converts filterObjects to query expressions', function (assert) {
|
||||
assert.ok(ResourceFilter);
|
||||
const filter = new ResourceFilter({
|
||||
type: 'oidc',
|
||||
status: ['active', 'pending'],
|
||||
});
|
||||
const expected =
|
||||
'("/item/type" == "oidc") and ("/item/status" == "active" or "/item/status" == "pending")';
|
||||
assert.equal(filter.queryExpression, expected);
|
||||
});
|
||||
});
|
||||
@@ -13,6 +13,7 @@ export default class ScopesScopeProjectsSessionsRoute extends Route {
|
||||
|
||||
@service ipc;
|
||||
@service session;
|
||||
@service resourceFilterStore;
|
||||
|
||||
// =attributes
|
||||
|
||||
@@ -52,8 +53,7 @@ export default class ScopesScopeProjectsSessionsRoute extends Route {
|
||||
const { id: scope_id } = this.modelFor('scopes.scope');
|
||||
const { user_id } = this.session.data.authenticated;
|
||||
await this.store.query('target', { recursive: true, scope_id });
|
||||
return await this.store.query('session', {
|
||||
filter: `"/item/user_id" == "${user_id}"`,
|
||||
return await this.resourceFilterStore.queryBy('session', { user_id }, {
|
||||
recursive: true,
|
||||
scope_id
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user