Merge pull request #844 from hashicorp/feature-resource-filter-system
Resource filter param system
This commit is contained in:
5 files changed
+162
-1
No files matched your search
@@ -10,7 +10,7 @@ import { inject as service } from '@ember/service';
|
||||
* type: 'oidc',
|
||||
* status: ['active', 'pending']
|
||||
* });
|
||||
* console.log(filter.queryExpression);
|
||||
* log(filter.queryExpression);
|
||||
* // ("/item/type" == "oidc") and ("/item/status" == "active" or "/item/status" == "pending")
|
||||
*/
|
||||
export class ResourceFilter {
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
/**
|
||||
* A resource filter param is a concise way to express a route query parameter.
|
||||
* Resource filter params abstract away a route's query parameter
|
||||
* interface, treating a query param as a simple attribute on a route instance.
|
||||
* Getting the attribute value is equivalent to looking up the associated query
|
||||
* parameter. Setting the attribute is equivalent to transitioning to the route
|
||||
* and passing the associated query parameter value.
|
||||
*
|
||||
* Additionally, resource filter params may declare `allowedValues`, an array
|
||||
* containing the set of values the parameter may take. While unenforced,
|
||||
* `allowedValues` are useful metadata about a resource filter and may be fetch
|
||||
* via `ResourceFilterParamHelper`. An optional default value may be specified
|
||||
* via `defaultValue` passed to the decorator.
|
||||
*
|
||||
* @see ResourceFilterParamHelper
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* export default class MyRoute extends Route {
|
||||
*
|
||||
* @resourceFilterParam(['active', 'pending'], ['active'])
|
||||
* status;
|
||||
*
|
||||
* @action
|
||||
* changeStatus(status) {
|
||||
* // Sets query param `filter-status` on the current route, which occurs
|
||||
* // via a route transition.
|
||||
* this.status = status;
|
||||
* // Log the value of query param `filter-status`.
|
||||
* log(this.status);
|
||||
* }
|
||||
* }
|
||||
*
|
||||
*/
|
||||
export function resourceFilterParam(allowedValues, defaultValue) {
|
||||
/**
|
||||
* @param {object} target
|
||||
* @param {string} name
|
||||
* @param {object} descriptor
|
||||
* @return {object{get, set}}
|
||||
*/
|
||||
return function (target, name /*, descriptor*/) {
|
||||
const filterKey = `filter-${name}`;
|
||||
const filterAllowedValuesKey = `filter-allowed-values-${name}`;
|
||||
|
||||
// If the route has no query params specified yet, declare them.
|
||||
if (!Object.keys(target.queryParams).length) target.queryParams = {};
|
||||
|
||||
// Add the resource filter query parameter to the route. Resource filter
|
||||
// param changes refresh the model but do not contribute to browser history.
|
||||
// See https://guides.emberjs.com/release/routing/query-params/
|
||||
target.queryParams[filterKey] = {
|
||||
refreshModel: true,
|
||||
replace: true,
|
||||
};
|
||||
|
||||
// Store the allowed values for future lookup
|
||||
// (via `ResourceFilterParamHelper`).
|
||||
target[filterAllowedValuesKey] = allowedValues;
|
||||
|
||||
// Override the decorated attribute with a getter and setter.
|
||||
return {
|
||||
/**
|
||||
* Returns the JSON-parsed query parameter value OR defaultValue.
|
||||
*/
|
||||
get() {
|
||||
const value =
|
||||
this.paramsFor(this.routeName)[filterKey] ||
|
||||
JSON.stringify(defaultValue);
|
||||
return value ? JSON.parse(value) : null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the resource filter param to the stringified representation
|
||||
* of `value`. NOTE: this is equivalent to transitioning into the
|
||||
* current route, changing the associated query param.
|
||||
* @param value
|
||||
*/
|
||||
set(value) {
|
||||
const queryParams = {};
|
||||
queryParams[filterKey] = JSON.stringify(value);
|
||||
this.transitionTo({ queryParams });
|
||||
},
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
import Helper from '@ember/component/helper';
|
||||
import { inject as service } from '@ember/service';
|
||||
import { getOwner } from '@ember/application';
|
||||
import { action } from '@ember/object';
|
||||
|
||||
/**
|
||||
* Use this helper to fetch the current value of a resource filter param,
|
||||
* as well as its allowedValues.
|
||||
*
|
||||
* @see resourceFilterParam (decorator)
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* {{#with resource-filter-param 'status' as |param|}}
|
||||
* {{param.name}} / {{param.value}} / {{param.selectedValue}}
|
||||
* {{/with}}
|
||||
*/
|
||||
export default class ResourceFilterParamHelper extends Helper {
|
||||
// =services
|
||||
|
||||
@service router;
|
||||
|
||||
// =methods
|
||||
|
||||
// =lifecycle management methods
|
||||
|
||||
/**
|
||||
* Recompute this helper when the route changes.
|
||||
*/
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.router.on('routeDidChange', this.routeDidChange);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop listening to route events when this helper is destroyed.
|
||||
*/
|
||||
willDestroy() {
|
||||
this.router.off('routeDidChange', this.routeDidChange);
|
||||
super.willDestroy();
|
||||
}
|
||||
|
||||
// =compute method
|
||||
|
||||
/**
|
||||
* Returns an object containing `name`, `value`, and `selectedValue`.
|
||||
* `name` - The name of the resource filter param.
|
||||
* `value` - The value of the resource filter param
|
||||
* @return {object}
|
||||
*/
|
||||
compute([routeName, name]) {
|
||||
const owner = getOwner(this);
|
||||
// Filter options
|
||||
const route = owner.lookup(`route:${routeName}`);
|
||||
const filterAllowedValuesKey = `filter-allowed-values-${name}`;
|
||||
const allowedValues = route[filterAllowedValuesKey];
|
||||
// Selected filters
|
||||
const rawValue = route[name];
|
||||
const selectedValue = rawValue || null;
|
||||
return { name, allowedValues, selectedValue };
|
||||
}
|
||||
|
||||
// =actions
|
||||
|
||||
/**
|
||||
* Triggers a recompute (see above) when the route changes, especially when
|
||||
* route query params change.
|
||||
*/
|
||||
@action
|
||||
routeDidChange() {
|
||||
this.recompute();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export { default } from 'core/decorators/resource-filter-param';
|
||||
@@ -0,0 +1 @@
|
||||
export { default } from 'core/helpers/resource-filter-param';
|
||||
Reference in new issue
Block a user