Files
redash/client/app/services/parameters/Parameter.js
Levko Kravets a682265e13 Migrate router and <app-view> to React (#4525)
* Migrate router and <app-view> to React: skeleton

* Update layout on route change

* Start moving page routes from angular to react

* Move page routes to react except of public dashboard and visualization embed)

* Move public dashboard and visualization embed routes to React

* Replace $route/$routeParams usages

* Some cleanup

* Replace AngularJS $location service with implementation based on history library

* Minor fix to how ApplicationView handles route change

* Explicitly use global layout for each page instead of handling related stuff in ApplicationArea component

* Error handling

* Remove AngularJS and related dependencies

* Move Parameter factory method to a separate file

* Fix CSS (replace custom components with classes)

* Fix: keep other url parts when updating location partially; refine code

* Fix tests

* Make router work in multi-org mode (respect <base> tag)

* Optimzation: don't resolve route if path didn't change

* Fix search input in header; error handling improvement (handle more errors in pages; global error handler for unhandled errors; dialog dismiss 'unhandled rejection' errors)

* Fix page keys; fix navigateTo calls (third parameter not available)

* Use relative links

* Router: ignore location REPLACE events, resolve only on PUSH/POP

* Fix tests

* Remove unused jQuery reference

* Show error from backend when creating Destination

* Remove route.resolve where not necessary (used constant values)

* New Query page: keep state on saving, reload when creating another new query

* Use currentRoute.key instead of hard-coded keys for page components

* Tidy up Router

* Tidy up location service

* Fix tests

* Don't add parameters changes to browser's history

* Fix test (improved fix)

Co-authored-by: Gabriel Dutra <nesk.frz@gmail.com>
2020-01-20 20:56:37 +02:00

125 lines
2.8 KiB
JavaScript

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;