client/app/services/parameters/Parameter.js (91 lines of code) (raw):
import { isNull, isObject, isFunction, isUndefined, isEqual, has, omit, isArray, each } from "lodash";
class Parameter {
constructor(parameter, parentQueryId) {
this.title = parameter.title;
this.name = parameter.name;
this.type = parameter.type;
this.global = parameter.global; // backward compatibility in Widget service
this.parentQueryId = parentQueryId;
// Used for meta-parameters (i.e. dashboard-level params)
this.locals = [];
// Used for URL serialization
this.urlPrefix = "p_";
}
static getExecutionValue(param, extra = {}) {
if (!isObject(param) || !isFunction(param.getExecutionValue)) {
return null;
}
return param.getExecutionValue(extra);
}
static setValue(param, value) {
if (!isObject(param) || !isFunction(param.setValue)) {
return null;
}
return param.setValue(value);
}
get isEmpty() {
return isNull(this.normalizedValue);
}
get hasPendingValue() {
return this.pendingValue !== undefined && !isEqual(this.pendingValue, this.normalizedValue);
}
/** Get normalized value to be used in inputs */
get normalizedValue() {
return this.$$value;
}
isEmptyValue(value) {
return isNull(this.normalizeValue(value));
}
// eslint-disable-next-line class-methods-use-this
normalizeValue(value) {
if (isUndefined(value)) {
return null;
}
return value;
}
updateLocals() {
if (isArray(this.locals)) {
each(this.locals, local => {
local.setValue(this.value);
});
}
}
setValue(value) {
const normalizedValue = this.normalizeValue(value);
this.value = normalizedValue;
this.$$value = normalizedValue;
this.updateLocals();
this.clearPendingValue();
return this;
}
/** Get execution value for a query */
getExecutionValue() {
return this.value;
}
setPendingValue(value) {
this.pendingValue = this.normalizeValue(value);
}
applyPendingValue() {
if (this.hasPendingValue) {
this.setValue(this.pendingValue);
}
}
clearPendingValue() {
this.pendingValue = undefined;
}
/** Update URL with Parameter value */
toUrlParams() {
const prefix = this.urlPrefix;
// `null` removes the parameter from the URL in case it exists
return {
[`${prefix}${this.name}`]: !this.isEmpty ? this.value : null,
};
}
/** Set parameter value from the URL */
fromUrlParams(query) {
const prefix = this.urlPrefix;
const key = `${prefix}${this.name}`;
if (has(query, key)) {
this.setValue(query[key]);
}
}
toQueryTextFragment() {
return `{{ ${this.name} }}`;
}
/** Get a saveable version of the Parameter by omitting unnecessary props */
toSaveableObject() {
return omit(this, ["$$value", "urlPrefix", "pendingValue", "parentQueryId"]);
}
}
export default Parameter;