(dispatch, getState) => {
    const isNumberFilter = filter.type === 'number';
    const isDateFilter = filter.type === 'date';
    const isStringFilter = filter.type === 'string';

    const availableFields = getAvailableFields(getState());

    if (filter.name && (isNumberFilter || isDateFilter) &&
      (filter.min === null || filter.min === undefined
        || filter.max === null || filter.max === undefined)) {
      dispatch(getFilterMinMax(filter));

      // We automatically add a new empty filter when the user
      // as selected the column of the current one
      if (availableFields.length) {
        dispatch(addFilter({}));
      }
    } else if (filter.name && isStringFilter && !filter.possibleValues) {
      dispatch(getFilterPossibleValues(filter));

      // We automatically add a new empty filter when the user
      // as selected the column of the current one
      if (availableFields.length) {
        dispatch(addFilter({}));
      }
    }
  }
  (dispatch, getState) => {
    const availableFields = getAvailableFields(getState());
    dispatch({
      type: REMOVE_FILTER,
      payload: filter
    });

    // If the user removed the last filter, we automatically
    // add a new empty one
    if (availableFields.length === 0) {
      dispatch(addFilter({}));
    }
  }
 (dispatch, getState) => {
   const bookmarksCount = getBookmarks(getState()).length;
   dispatch({
     type: ADD_BOOKMARK,
     payload: {
       name: `Bookmark #${bookmarksCount + 1}`,
       filters: getNonEmptyFilters(getState()).map(filter => (
         // We remove the min, max, possibleValues and some
         // other attributes from the bookmark because the
         // dataset can change over time
         Object.assign({}, { name: filter.name, type: filter.type, values: filter.values })
       ))
     }
   });
   dispatch(saveBookmarksToStorage());
 }
  (dispatch, getState) => {
    // First, we remove all the filters
    dispatch(resetFilters());

    // Then, for each filter saved in the bookmark,
    // we check if the field still exists and is available
    bookmark.filters.forEach((filter) => {
      const fields = getAvailableFields(getState());
      if (fields.findIndex(f => f.name === filter.name) !== -1) {
        dispatch(addFilter(filter));
      }
    });

    // After resetting the filters, by default an empty one
    // has been added. Another has also been appended after the
    // last one.
    // We remove the very first one.
    const filters = getFilters(getState());
    if (bookmark.filters.length && filters.length && !filters[0].name) {
      dispatch(removeFilter(filters[0]));
    }
  }
 bookmark.filters.forEach((filter) => {
   const fields = getAvailableFields(getState());
   if (fields.findIndex(f => f.name === filter.name) !== -1) {
     dispatch(addFilter(filter));
   }
 });
const mapStateToProps = state => ({
  fields: getAvailableFields(state),
  filters: getFilters(state)
});