all files / src/explore/ store.js

54.76% Statements 46/84
16.98% Branches 9/53
62.5% Functions 10/16
53.95% Lines 41/76
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141    400×       36× 102× 162×                                                                                                                                               162× 162×   162× 16×     16×     146×         152×                 200×              
/* eslint camelcase: 0 */
import controls from './controls';
import visTypes, { sectionsToRender } from './visTypes';
 
export function getFormDataFromControls(controlsState) {
  const formData = {};
  Object.keys(controlsState).forEach((controlName) => {
    formData[controlName] = controlsState[controlName].value;
  });
  return formData;
}
 
export function getControlNames(vizType, datasourceType) {
  const controlNames = [];
  sectionsToRender(vizType, datasourceType).forEach(
    section => section.controlSetRows.forEach(
      fsr => fsr.forEach(
        f => controlNames.push(f))));
  return controlNames;
}
 
function handleDeprecatedControls(formData) {
  // Reacffectation / handling of deprecated controls
  /* eslint-disable no-param-reassign */
 
  // y_axis_zero was a boolean forcing 0 to be part of the Y Axis
  if (formData.y_axis_zero) {
    formData.y_axis_bounds = [0, null];
  }
}
 
export function getControlsState(state, form_data) {
  /*
  * Gets a new controls object to put in the state. The controls object
  * is similar to the configuration control with only the controls
  * related to the current viz_type, materializes mapStateToProps functions,
  * adds value keys coming from form_data passed here. This can't be an action creator
  * just yet because it's used in both the explore and dashboard views.
  * */
 
  // Getting a list of active control names for the current viz
  const formData = Object.assign({}, form_data);
  const vizType = formData.viz_type || 'table';
 
  handleDeprecatedControls(formData);
 
  const controlNames = getControlNames(vizType, state.datasource.type);
 
  const viz = visTypes[vizType];
  const controlOverrides = viz.controlOverrides || {};
  const controlsState = {};
  controlNames.forEach((k) => {
    const control = Object.assign({}, controls[k], controlOverrides[k]);
    if (control.mapStateToProps) {
      Object.assign(control, control.mapStateToProps(state, control));
      delete control.mapStateToProps;
    }
 
    formData[k] = (control.multi && formData[k] && !Array.isArray(formData[k])) ? [formData[k]]
      : formData[k];
 
    // If the value is not valid anymore based on choices, clear it
    if (control.type === 'SelectControl' && control.choices && k !== 'datasource' && formData[k]) {
      const choiceValues = control.choices.map(c => c[0]);
      if (control.multi && formData[k].length > 0 && choiceValues.indexOf(formData[k][0]) < 0) {
        delete formData[k];
      } else if (!control.multi && !control.freeForm && choiceValues.indexOf(formData[k]) < 0) {
        delete formData[k];
      }
    }
    // Removing invalid filters that point to a now inexisting column
    if (control.type === 'FilterControl' && control.choices) {
      if (!formData[k]) {
        formData[k] = [];
      }
      const choiceValues = control.choices.map(c => c[0]);
      formData[k] = formData[k].filter(flt => choiceValues.indexOf(flt.col) >= 0);
    }
 
    if (typeof control.default === 'function') {
      control.default = control.default(control);
    }
    control.validationErrors = [];
    control.value = formData[k] !== undefined ? formData[k] : control.default;
    controlsState[k] = control;
  });
  if (viz.onInit) {
    return viz.onInit(controlsState);
  }
  return controlsState;
}
 
export function applyDefaultFormData(form_data) {
  const datasourceType = form_data.datasource.split('__')[1];
  const vizType = form_data.viz_type || 'table';
  const viz = visTypes[vizType];
  const controlNames = getControlNames(vizType, datasourceType);
  const controlOverrides = viz.controlOverrides || {};
  const formData = {};
  controlNames.forEach((k) => {
    const control = Object.assign({}, controls[k]);
    if (controlOverrides[k]) {
      Object.assign(control, controlOverrides[k]);
    }
    if (form_data[k] === undefined) {
      if (Itypeof control.default === 'function') {
        formData[k] = control.default(controls[k]);
      } else {
        formData[k] = control.default;
      }
    } else {
      formData[k] = form_data[k];
    }
  });
  // fill in additional params stored in form_data but not used by control
  Object.keys(form_data)
    .forEach((key) => {
      if (formData[key] === undefined) {
        formData[key] = form_data[key];
      }
    });
  return formData;
}
 
export const autoQueryControls = [
  'datasource',
  'viz_type',
];
 
const defaultControls = Object.assign({}, controls);
Object.keys(controls).forEach((f) => {
  defaultControls[f].value = controls[f].default;
});
 
const defaultState = {
  controls: defaultControls,
  form_data: getFormDataFromControls(defaultControls),
};
 
export { defaultControls, defaultState };