<commit_before>/* ExplorerStore */

var AppDispatcher = require('../dispatcher/AppDispatcher');
var EventEmitter = require('events').EventEmitter;
var _ = require('lodash');
var ExplorerConstants = require('../constants/ExplorerConstants');
var FormatUtils = require('../utils/FormatUtils');
var ExplorerUtils = require('../utils/ExplorerUtils');
var FilterUtils = require('../utils/FilterUtils');
var ProjectUtils = require('../utils/ProjectUtils');
var ProjectStore = require('./ProjectStore');

var CHANGE_EVENT = 'change';

var _explorers = {};

function _defaultAttrs(){
  return {
    id: FormatUtils.generateTempId(),
    query_name: null,
    active: false,
    saving: false,
    error: null,
    result: null,
    loading: false,
    isValid: true,
    refresh_rate: 0,
    query: {
      event_collection: null,
      analysis_type: null,
      target_property: null,
      percentile: null,
      group_by: null,
      interval: null,
      timezone: ProjectUtils.getConstant('DEFAULT_TIMEZONE'),
      filters: null,
      email: null,
      latest: null,
      filters: [],
      time: {
        relativity: 'this',
        amount: 14,
        sub_timeframe: 'days'
      }
    },
    metadata: {
      display_name: null,
      visualization: {
        chart_type: null
      }
    }
  };
}

function _defaultFilter() {
  return {
    property_name: null,
    property_value: null,
    operator: 'eq',
    coercion_type: 'String'
  };
}

function _defaultGeoFilter() {
  return {
    coordinates: [],
    max_distance_miles: null
  };
}

function _defaultStep() {
  return {
    event_collection: null,
    actor_property: null,
    time: {
      relativity: 'this',
      amount: 14,
      sub_timeframe: 'days'
    },
    timezone: ProjectUtils.getConstant('DEFAULT_TIMEZONE'),
    filters: [],
    optional: false,
    inverted: false,
    active: false
  }
}

/**
 * Get the default coercion type for this filter based off the filter's property_name's set type
 * in the project schema.
 * @param  {Object} explorer  The explorer model that the filter belongs to
 * @param  {Object} filter    The filter
 * @return {String}           The default coercion type
 */
function _getDefaultFilterCoercionType(explorer, filter) {
  var propertyType = ProjectUtils.getPropertyType(
    ProjectStore.getProject(),
    explorer.query.event_collection,
    filter.property_name);
  return targetCoercionType = FormatUtils.coercionTypeForPropertyType(propertyType);
}

/**
 * Runs through the changeset and moves data around if necessary
 * @param {Object} explorer   The explorer model that is being updated
 * @param {Object} updates    The updated explorer model
 * @return {Object}           The new set of updates
 */
function _prepareUpdates(explorer, updates) {
  var newModel = _.assign({}, explorer, updates);

  newModel = _removeEmailExtractionFields(explorer, newModel);
  newModel = _migrateFunnelSteps(explorer, newModel);

  return newModel;
}

/**
 * If the query got changed to a funnel, move the step-specific parameters to a steps object.
 * and vice versa if it got changed FROM a funnel
 * @param {Object} explorer The explorer model that is being updated
 * @param {Object} newModel The updated explorer model
 * @return {Object}         The new set of updates
 */
function _migrateFunnelSteps(explorer, newModel) {
  var sharedProperties = ['event_collection', 'time', 'timezone', 'filters']
  if(newModel.query.analysis_type === 'funnel' && explorer.query.analysis_type !== 'funnel') {
    // Changing TO funnels
    var firstStep = _defaultStep();
    firstStep.active = true;

    _.each(sharedProperties, function (key) {
      if(typeof(explorer.query[key]) !== 'undefined' && explorer.query[key] !== null) {
        firstStep[key] = explorer.query[key] 
      }      

      delete newModel.query[key]
    });

    if(typeof(explorer.query.target_property) !== 'undefined' && explorer.query.target_property !== null) {
      firstStep.actor_property = explorer.query.target_property;
      delete explorer.query.target_property;
    }

    newModel.query.steps = [firstStep];

  } else if (newModel.query.analysis_type !== 'funnel' && explorer.query.analysis_type === 'funnel') {
    // Changing FROM funnels
    var activeStep = _.find(explorer.query.steps, function (step) {
      return step.active
    });

    _.each(sharedProperties, function (key) {
      if(typeof(activeStep[key]) !== 'undefined') {
        newModel.query[key] = activeStep[key];
      }
    });

    if(activeStep.actor_property !== null) {
      newModel.query.target_property = activeStep.actor_property;
    }

    delete newModel.query.steps;<commit_msg>use lodash for undefined and null checks<commit_after>/* ExplorerStore */

var AppDispatcher = require('../dispatcher/AppDispatcher');
var EventEmitter = require('events').EventEmitter;
var _ = require('lodash');
var ExplorerConstants = require('../constants/ExplorerConstants');
var FormatUtils = require('../utils/FormatUtils');
var ExplorerUtils = require('../utils/ExplorerUtils');
var FilterUtils = require('../utils/FilterUtils');
var ProjectUtils = require('../utils/ProjectUtils');
var ProjectStore = require('./ProjectStore');

var CHANGE_EVENT = 'change';

var _explorers = {};

function _defaultAttrs(){
  return {
    id: FormatUtils.generateTempId(),
    query_name: null,
    active: false,
    saving: false,
    error: null,
    result: null,
    loading: false,
    isValid: true,
    refresh_rate: 0,
    query: {
      event_collection: null,
      analysis_type: null,
      target_property: null,
      percentile: null,
      group_by: null,
      interval: null,
      timezone: ProjectUtils.getConstant('DEFAULT_TIMEZONE'),
      filters: null,
      email: null,
      latest: null,
      filters: [],
      time: {
        relativity: 'this',
        amount: 14,
        sub_timeframe: 'days'
      }
    },
    metadata: {
      display_name: null,
      visualization: {
        chart_type: null
      }
    }
  };
}

function _defaultFilter() {
  return {
    property_name: null,
    property_value: null,
    operator: 'eq',
    coercion_type: 'String'
  };
}

function _defaultGeoFilter() {
  return {
    coordinates: [],
    max_distance_miles: null
  };
}

function _defaultStep() {
  return {
    event_collection: null,
    actor_property: null,
    time: {
      relativity: 'this',
      amount: 14,
      sub_timeframe: 'days'
    },
    timezone: ProjectUtils.getConstant('DEFAULT_TIMEZONE'),
    filters: [],
    optional: false,
    inverted: false,
    active: false
  }
}

/**
 * Get the default coercion type for this filter based off the filter's property_name's set type
 * in the project schema.
 * @param  {Object} explorer  The explorer model that the filter belongs to
 * @param  {Object} filter    The filter
 * @return {String}           The default coercion type
 */
function _getDefaultFilterCoercionType(explorer, filter) {
  var propertyType = ProjectUtils.getPropertyType(
    ProjectStore.getProject(),
    explorer.query.event_collection,
    filter.property_name);
  return targetCoercionType = FormatUtils.coercionTypeForPropertyType(propertyType);
}

/**
 * Runs through the changeset and moves data around if necessary
 * @param {Object} explorer   The explorer model that is being updated
 * @param {Object} updates    The updated explorer model
 * @return {Object}           The new set of updates
 */
function _prepareUpdates(explorer, updates) {
  var newModel = _.assign({}, explorer, updates);

  newModel = _removeEmailExtractionFields(explorer, newModel);
  newModel = _migrateFunnelSteps(explorer, newModel);

  return newModel;
}

/**
 * If the query got changed to a funnel, move the step-specific parameters to a steps object.
 * and vice versa if it got changed FROM a funnel
 * @param {Object} explorer The explorer model that is being updated
 * @param {Object} newModel The updated explorer model
 * @return {Object}         The new set of updates
 */
function _migrateFunnelSteps(explorer, newModel) {
  var sharedProperties = ['event_collection', 'time', 'timezone', 'filters']
  if(newModel.query.analysis_type === 'funnel' && explorer.query.analysis_type !== 'funnel') {
    // Changing TO funnels
    var firstStep = _defaultStep();
    firstStep.active = true;

    _.each(sharedProperties, function (key) {
      if(!_.isUndefined(explorer.query[key]) && !_.isNull(explorer.query[key])) {
        firstStep[key] = explorer.query[key] 
      }      

      delete newModel.query[key]
    });

    if(!_.isUndefined(explorer.query.target_property) && !_.isNull(explorer.query.target_property)) {
      firstStep.actor_property = explorer.query.target_property;
      delete explorer.query.target_property;
    }

    newModel.query.steps = [firstStep];

  } else if (newModel.query.analysis_type !== 'funnel' && explorer.query.analysis_type === 'funnel') {
    // Changing FROM funnels
    var activeStep = _.find(explorer.query.steps, function (step) {
      return step.active
    });

    _.each(sharedProperties, function (key) {
      if(!_.isUndefined(activeStep[key])) {
        newModel.query[key] = activeStep[key];
      }
    });

    if(!_.isNull(activeStep.actor_property)) {
      newModel.query.target_property = activeStep.actor_property;
    }

    delete newModel.query.steps;
{'fraction_non_alphanumeric': 0.11849000106940434, 'fraction_numerical': 0.0010694043417816277, 'mean_word_length': 3.3437064561077565, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7375060', 'n_tokens_mistral': 2814, 'n_tokens_neox': 2726, 'n_words': 705}