client/helpers/Util.js

import reduce from 'lodash/reduce';
import snakeCase from 'lodash/snakeCase';
import has from 'lodash/has';
import Logger from 'client/helpers/Logger';
import moment from 'moment';

export const checkServer = () => Object.prototype.toString.call(global.process) === '[object process]';

export const checkBrowser = () => !checkServer();

/**
 * convertError
 * convert backend eror to front-end
 * @param err
 * @memberof Util
 * @returns {*}
 */
export function convertError(err) {
  return (err && err.toJSON ? err.toJSON() : err) || {};
}
/**
 * serializeConfig
 * serialize config and take only fields for front-end
 * @param config
 * @memberof Util
 * @returns {*}
 */
export function serializeConfig(config) {
  return reduce(['images', 'itemsInAdmin', 'address', 'owner', 'admin_language_id'], (acc, key) => Object.assign(acc, { [key]: config.get(key) }), {});
}

/**
 * formClientLanguage
 * create map with languages, a stub for description usually
 * @param languages
 * @memberof Util
 * @returns {*}
 */
export function formClientLanguage(languages) {
  return languages.reduce((acc, item) => acc.concat(Object.assign({
    language_id: item.get('id'),
  })), []);
}

/**
 * mapLanguages
 * map languages on server from app object or from reducer from application state
 * @param props
 * @memberof Util
 * @returns {*}
 */
export function mapLanguages(props) {
  let mappedLanguages;
  if (checkServer()) {
    mappedLanguages = props.req.app.languages.map(item => ({ language_id: item.id }));
  } else {
    mappedLanguages = formClientLanguage(props.store.getState().getIn(['application', 'languages']));
  }
  return mappedLanguages;
}

/**
 * formBreadcrumbPath
 * forms path for breadcrumbs
 */
export function formBreadcrumbPath({
   resource, query, intl, last,
 }) {
  const crumbs = [
    { title: 'Home', link: '/admin/overview' },
    { title: intl.get(snakeCase(resource)), link: `/admin/${resource}` },
  ];
  if (last) {
    crumbs.push({ title: query.id === 'create' ? intl.get('create') : intl.get('update') });
  }
  return crumbs;
}

/**
 * recursiveSearch
 * search in array recursively
 * @param arr
 * @param value
 * @param id
 * @returns {*}
 */
export function recursiveSearch(arr, id, value = 'id') {
  if (arr) {
    const length = arr.size || arr.length;
    for (let i = 0; i < length; i += 1) {
      const el = arr.get ? arr.get(i) : arr[i];
      if (el.get && String(el.get(value)) === String(id)) {
        return el;
      }
      if (!el.get && String(el[value]) === String(id)) {
        return arr[i];
      }
      let found = null;
      if (el.get) {
        found = recursiveSearch(el.get('children'), id, value);
      } else {
        found = recursiveSearch(el.children, id, value);
      }

      if (found) {
        return found;
      }
    }
  }
  return null;
}

/**
 * compareColumns
 * compare table columns when sorting
 * @param column
 * @returns {function(*=, *=, *)}
 */
export const compareColumns = column => (a, b) => {
  if (!has(a, column) || !has(b, column)) {
    Logger.log(`Compare column: coulmn ${column} does't exists in table`);
  }
  if ((String(a[column]) === 'true' || String(a[column]) === 'false') && (String(b[column]) === 'true' || String(b[column]) === 'false')) {
    return a[column] - b[column];
  } else if (Number(a[column]) == a[column] && Number(b[column]) == b[column]) { // eslint-disable-line
    return a[column] - b[column];
  } else if (moment(a[column], 'dd.mm.yyy').isValid() && moment(b[column], 'dd.mm.yyy').isValid()) {
    return moment(a[column], 'dd.mm.yyy') - (moment(b[column], 'dd.mm.yyy'));
  }
  return (a[column] || '').localeCompare((b[column] || ''));
};

// base layout for inputs and labels
export const formItemLayout = {
  labelCol: {
    xs: { span: 24 },
    sm: { span: 5 },
  },
  wrapperCol: {
    xs: { span: 24 },
    sm: { span: 18 },
  },
};


// base layout for inputs and labels for all Filters
export const formItemFilterLayout = {
  labelCol: { span: 24 },
  wrapperCol: { span: 24 },
};


/**
 * setter
 * base function for setting fields on detail view
 * @param field
 * @param props
 * @returns {function(*): *}
 */
export const setter = (field, props) => ev => props
  .onSet({ path: `detail.data.${field}`, data: (ev && ev.target) ? ev.target.value : ev });

/**
 * setterDate
 * base function for setting fields on detail view
 * @param field
 * @param props
 * @returns {function(*): *}
 */
export const setterDate = (field, props) => ev => props
  .onSet({ path: `detail.data.${field}`, data: ev ? moment(ev).format('YYYY-MM-DD HH:mm:ss') : moment().format('YYYY-MM-DD HH:mm:ss') });
/**
 * setterSpread
 * spread all params in onSet used in LanguageInputBlock
 * @param props
 * @returns {function(*): *}
 */
export const setterSpread = (field, props) => ev => props
  .onSet({ path: `detail.data.${field}`, ...ev });

/**
 * createNewId
 * base function for create fake id for new data
 * @returns {id_fake}
 */
export const createNewId = () => `${Date.now()}-${Math.random()}_fake`;

/**
 * getStoreCaptchaPages
 * pages with possible captchas
 * @type {string[]}
 */
export const getStoreCaptchaPages = ([
  'register', 'guest_checkout', 'reviews', 'returns', 'contact',
]);
/**
 * getEmailNotifications
 * events with possible email notification
 * @type {string[]}
 */
export const getEmailNotifications = (['register', 'orders', 'reviews']);