Files
bigcapital/client/src/utils.js
Ahmed Bouhuolia 6d4b3164a8 feat: optimize sale estimate form performance.
feat: optimize sale receipt form performance.
feat: optimize sale invoice form performance.
feat: optimize bill form performance.
2020-11-12 20:44:22 +02:00

298 lines
7.3 KiB
JavaScript

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 : '';
}