import moment from 'moment'; import _ from 'lodash'; import { Intent, } from '@blueprintjs/core'; import Currency from 'js-money/lib/currency'; import PProgress from 'p-progress'; import accounting from 'accounting'; export function removeEmptyFromObject(obj) { obj = Object.assign({}, obj); var keys = Object.keys(obj); keys.forEach(function (key) { const value = obj[key]; if (value === '' || value === null || value === undefined) { delete obj[key]; } }); return obj; } export const optionsMapToArray = (optionsMap, service = '') => { return Object.keys(optionsMap).map((optionKey) => { const optionValue = optionsMap[optionKey]; return { key: service ? `${service}_${optionKey}` : `${optionKey}`, value: optionValue, }; }); }; export const optionsArrayToMap = (optionsArray) => { return optionsArray.reduce((map, option) => { map[option.key] = option.value; return map; }, {}); }; export function numberComma(number) { number = typeof number === 'number' ? String(number) : number; const parts = number.split('.'); const integer = parts[0] || '0'; const decimal = parts[1]; const postfix = decimal ? `.${decimal}` : ''; return `${integer.replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,')}${postfix}`; } export const momentFormatter = (format) => { return { formatDate: (date) => moment(date).format(format), parseDate: (str) => moment(str, format).toDate(), placeholder: `${format}`, }; }; /** Event handler that exposes the target element's value as a boolean. */ export const handleBooleanChange = (handler) => { return (event) => handler(event.target.checked); }; /** Event handler that exposes the target element's value as a string. */ export const handleStringChange = (handler) => { return (event) => handler(event.target.value); }; /** Event handler that exposes the target element's value as a number. */ export const handleNumberChange = (handler) => { return handleStringChange((value) => handler(+value)); }; export const handleDateChange = (handler) => { return (date) => handler(moment(date).format('YYYY-MM-DD'), date); }; export const objectKeysTransform = (obj, transform) => { return Object.keys(obj).reduce((acc, key) => { const computedKey = transform(key); acc[computedKey] = obj[key]; return acc; }, {}); }; export const compose = (...funcs) => funcs.reduce( (a, b) => (...args) => a(b(...args)), (arg) => arg, ); export const getObjectDiff = (a, b) => { return _.reduce( a, (result, value, key) => { return _.isEqual(value, b[key]) ? result : result.concat(key); }, [], ); }; export const parseDateRangeQuery = (keyword) => { const queries = { today: { range: 'day', }, this_year: { range: 'year', }, this_month: { range: 'month', }, this_week: { range: 'week', }, }; if (typeof queries[keyword] === 'undefined') { throw new Error(`The date range query ${keyword} is not defined.`); } const query = queries[keyword]; return { from_date: moment().startOf(query.range).toDate(), to_date: moment().endOf(query.range).toDate(), }; }; export const defaultExpanderReducer = (tableRows, level) => { let currentLevel = 1; const expended = []; const walker = (rows, parentIndex = null) => { return rows.forEach((row, index) => { const _index = parentIndex ? `${parentIndex}.${index}` : `${index}`; expended[_index] = true; if (row.children && currentLevel < level) { walker(row.children, _index); } currentLevel++; }, {}); }; walker(tableRows); return expended; }; export function formattedAmount(cents, currency) { const { symbol, decimal_digits: precision } = Currency[currency]; const amount = cents / Math.pow(10, precision); return accounting.formatMoney(amount, { symbol, precision }); } export function formattedExchangeRate(amount, currency) { const options = { style: 'currency', currency: currency, minimumFractionDigits: 2, }; const formatter = new Intl.NumberFormat(undefined, options); return formatter.format(amount); } export const ConditionalWrapper = ({ condition, wrapper, children }) => condition ? wrapper(children) : children; export const checkRequiredProperties = (obj, properties) => { return properties.some((prop) => { const value = obj[prop]; return value === '' || value === null || value === undefined; }); }; export const saveFilesInAsync = (files, actionCb, extraTasks) => { const opers = []; files.forEach((file) => { const formData = new FormData(); formData.append('attachment', file.file); const oper = new PProgress((resolve, reject, progress) => { actionCb(formData, file, (requestProgress) => { progress(requestProgress); }) .then((data) => { resolve(data); }) .catch((error) => { reject(error); }); }); opers.push(oper); }); return PProgress.all(opers); }; export const firstLettersArgs = (...args) => { let letters = []; args.forEach((word) => { if (typeof word === 'string') { letters.push(word.charAt(0)); } }); return letters.join('').toUpperCase(); }; export const uniqueMultiProps = (items, props) => { return _.uniqBy(items, (item) => { return JSON.stringify(_.pick(item, props)); }); }; export const transformUpdatedRows = (rows, rowIndex, columnIdOrObj, value) => { const columnId = typeof columnIdOrObj !== 'object' ? columnIdOrObj : null; const updateTable = typeof columnIdOrObj === 'object' ? columnIdOrObj : null; const newData = updateTable ? updateTable : { [columnId]: value }; return rows.map((row, index) => { if (index === rowIndex) { return { ...rows[rowIndex], ...newData }; } return { ...row }; }); }; export const tansformDateValue = (date) => { return moment(date).toDate() || new Date(); }; export const repeatValue = (value, len) => { var arr = []; for (var i = 0; i < len; i++) { arr.push(value); } return arr; }; export const flatToNestedArray = ( data, config = { id: 'id', parentId: 'parent_id' }, ) => { const map = {}; const nestedArray = []; data.forEach((item) => { map[item[config.id]] = item; map[item[config.id]].children = []; }); data.forEach((item) => { const parentItemId = item[config.parentId]; if (!item[config.parentId]) { nestedArray.push(item); } if (parentItemId) { map[parentItemId].children.push(item); } }); return nestedArray; }; export const orderingLinesIndexes = (lines, attribute = 'index') => { return lines.map((line, index) => ({ ...line, [attribute]: index + 1 })); }; export const transformToObject = (arr, key) => { return arr.reduce(function(acc, cur, i) { acc[key ? cur[key] : i] = cur; return acc; }, {}); } export const itemsStartWith = (items, char) => { return items.filter((item) => item.indexOf(char) === 0); }; export const saveInvoke = (func, ...rest) => { return func && func(...rest); } export const transformToForm = (obj, emptyInitialValues) => { return _.pickBy( obj, (val, key) => val !== null && Object.keys(emptyInitialValues).includes(key), ) } export function inputIntent({ error, touched }){ return error && touched ? Intent.DANGER : ''; }