mirror of
https://github.com/getredash/redash.git
synced 2026-03-22 10:00:17 -04:00
* 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>
125 lines
2.8 KiB
JavaScript
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;
|