import JSBI from 'jsbi'; import chroma from "chroma-js"; import * as htmlToImage from 'html-to-image'; export function debounce(callback, wait, context = this) { let timeout = null; let callbackArgs = null; const later = () => callback.apply(context, callbackArgs); return function (...args) { callbackArgs = args; clearTimeout(timeout); timeout = setTimeout(later, wait); }; } export function getResourceName(url = '') { return url.split('/').filter(s => s!== '').pop(); } /* eslint-disable no-mixed-operators */ export function randomInt(a, b) { const min = (b ? a : 0) - 0.5; const max = b || a || Number.MAX_SAFE_INTEGER; const rand = min - 0.5 + (Math.random() * (max - min + 1)); return Math.round(rand); } export const fileNameFormat = (str = '', ext = '') => { const name = str.replace(/[^a-zA-Z0-9]/g, '_'); return `${name}${ext}`; }; export const toUnderscore = s => s.split(/(?=[A-Z])/).join('_').toLowerCase(); export const getUniqueFilter = keys => (item, i, list) => !list.some((item2, j) => j < i && keys.every(key => item[ key ] === item2[ key ] && item[ key ] !== undefined)); export const numberWithCommas = (x) => x ? x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',') : 0; export const numberCompact = (x) => x >= 1000 ? x / 1000 + 'k': x; export const cutURL = (url, prefix = '.../') => `${ prefix + url.split('/').slice(3).join('/') }`; export const escapeRegExp = string => string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); export function getRE(string, options) { let re; try { re = new RegExp(string, options); } catch(e){ re = new RegExp(escapeRegExp(string), options); } return re; } export const getStateColor = (state) => { switch (state) { case 'passed': return 'green'; case 'failed': return 'red'; default: return 'gray-medium'; } }; export const convertNumberRange = (oldMax, oldMin, newMin, newMax, currentValue) => { let newValue; let newRange; const oldRange = (oldMax - oldMin); if (oldRange === 0) { newValue = newMin; } else { newRange = (newMax - newMin); newValue = (((currentValue - oldMin) * newRange) / oldRange) + newMin; } return newValue; }; export const prorata = ({ parts, elements, startDivisorFn, divisorFn, }) => { const byElement = Object.entries(elements) .reduce((ack, [ element, numElements ]) => ({ ...ack, [ element ]: { parts: 0, elements: numElements, divisor: startDivisorFn(numElements) }, }), {}); while (parts > 0) { const element = Object.entries(byElement).reduce((a, [ k, v ]) => (a.divisor > v.divisor ? a : v), { divisor: 0 }); // eslint-disable-next-line no-plusplus element.parts++; element.divisor = divisorFn(element.elements, element.parts); // eslint-disable-next-line no-plusplus parts--; } return Object.entries(byElement).reduce((a, [ k, v ]) => ({ ...a, [ k ]: v.parts }), {}); }; export const titleCase = (str) => { str = str.toLowerCase(); str = str.split('_'); for (var i = 0; i < str.length; i++) { str[i] = str[i].charAt(0).toUpperCase() + str[i].slice(1); } return str.join(' '); } export const confirm = (message, callback) => { const sure = window.confirm(message); if (!sure) return; callback() } const KB = 1<<10; const MB = KB<<10; const GB = MB<<10; export function formatBytes(bt: number): string { if (bt > GB) { return `${ Math.trunc(bt/GB*1e2)/1e2 }GB`; } if (bt > MB) { return `${ Math.trunc(bt/MB*1e2)/1e2 }MB`; } if (bt > KB) { return `${ Math.trunc(bt/KB*1e2)/1e2 }KB`; } return `${ bt }B`; } export function percentOf(part: number, whole: number):number { return whole > 0 ? (part * 100) / whole : 0; } export function fileType(url) { return url.split(/[#?]/)[0].split('.').pop().trim() } export function fileName(url) { if (url) { var m = url.toString().match(/.*\/(.+?)\./); if (m && m.length > 1) { return `${m[1]}.${fileType(url)}`; } } return ""; } export const camelCased = (val) => val.replace(/_([a-z])/g, function (g) { return g[1].toUpperCase(); }) export function capitalize(s: string) { if (s.length === 0) return s; return s[0].toUpperCase() + s.slice(1); } export const titleize = (str) => { let upper = true let newStr = "" for (let i = 0, l = str.length; i < l; i++) { // Note that you can also check for all kinds of spaces with // str[i].match(/\s/) if (str[i] == " ") { upper = true newStr += str[i] continue } if (str[i] == "_") { upper = true newStr += ' ' continue } newStr += upper ? str[i].toUpperCase() : str[i].toLowerCase() upper = false } return newStr } /** * (BigInt('2783377641436327') * BigInt(id) % BigInt('4503599627370496') + BigInt('4503599627370496')).toString() * Replacing the above line of BigInt with JSBI since the BigInt not supportiing the some of the browser (i.e Safari (< 14), Opera). */ export const hashProjectID = (id) => { if (!!id) { return JSBI.add( JSBI.remainder( JSBI.multiply(JSBI.BigInt('2783377641436327'), JSBI.BigInt(id)), JSBI.BigInt('4503599627370496') ), JSBI.BigInt('4503599627370496') ).toString() } return '' } export const colorScale = (values, colors) => { return chroma.scale(colors) } export const truncate = (input, max = 10) => input.length > max ? `${input.substring(0, max)}...` : input; export const iceServerConfigFromString = (str) => { if (!str || typeof str !== 'string'|| str.length === 0) { return null; } return str.split("|").map(function(c) { let server = null const arr = c.split(",") if (!!arr[0] !== "") { server = {} server.urls = arr[0] if (!!arr[1]) { server.username = arr[1] if (!!arr[2]) { server.credential = arr[2] } } return server } }) } export const isGreaterOrEqualVersion = (version, compareTo) => { const [major, minor, patch] = version.split("-")[0].split('.'); const [majorC, minorC, patchC] = compareTo.split("-")[0].split('.'); return (major > majorC) || (major === majorC && minor > minorC) || (major === majorC && minor === minorC && patch >= patchC); } export const sliceListPerPage = (list, page, perPage = 10) => { const start = page * perPage; const end = start + perPage; return list.slice(start, end); } export const positionOfTheNumber = (min, max, value, length) => { const interval = (max - min) / length; const position = Math.round((value - min) / interval); return position; } export const convertElementToImage = async (el) => { const fontEmbedCss = await htmlToImage.getFontEmbedCSS(el); const image = await htmlToImage.toJpeg(el, { pixelRatio: 2, fontEmbedCss, filter: function (node) { return node.id !== 'no-print'; }, }); return image; } export const unserscoreToSpaceAndCapitalize = (str) => { return str.replace(/_/g, ' ').replace(/\w\S*/g, (txt) => { return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase(); }); } export const convertToCSV = (headers, objArray) => { var array = typeof objArray != 'object' ? JSON.parse(objArray) : objArray; var str = ''; const headersMap = headers.reduce((acc, curr) => { acc[curr.key] = curr; return acc; }, {}); str += headers.map(h => h.label).join(',') + '\r\n'; for (var i = 0; i < array.length; i++) { var line = ''; for (var index in headersMap) { if (line !== '') line += ','; line += array[i][index]; } str += line + '\r\n'; } return str; } export const exportCSVFile = (headers, items, fileTitle) => { var jsonObject = JSON.stringify(items); var csv = convertToCSV(headers, jsonObject); var exportedFilenmae = fileTitle + '.csv' || 'export.csv'; var blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' }); if (navigator.msSaveBlob) { // IE 10+ navigator.msSaveBlob(blob, exportedFilenmae); } else { var link = document.createElement("a"); if (link.download !== undefined) { var url = URL.createObjectURL(blob); link.setAttribute("href", url); link.setAttribute("download", exportedFilenmae); link.style.visibility = 'hidden'; document.body.appendChild(link); link.click(); document.body.removeChild(link); } } } export const fetchErrorCheck = (response: any) => { if (!response.ok) { throw Error(response.statusText); } return response.json(); }