import { type AutocompleteItemType } from './components/autocomplete-item'; export function getLastIndexOfSubstringIgnoreCase( string: string, substring: string ) { return string.toLowerCase().lastIndexOf(substring.toLowerCase()); } export type BasicItem = { label?: string; id: string; tags?: string[]; items?: BasicItem[]; }; export const getNodePaths = >( items: Item[], id?: string, path: Item[] = [] ) => { let nodePaths: Omit[][] = []; items.forEach((node) => { const { items, ...thisNode } = node; const nodePath = [...path, thisNode]; if (items) { const result = getNodePaths(items, id, nodePath) as Omit< Item, 'items' >[][]; if (result.length) { nodePaths = [...nodePaths, ...result]; } } else if (!id || thisNode.id === id) { nodePaths = [...nodePaths, nodePath]; } }); return nodePaths; }; export function prepareTreeDataForAutocomplete>( flattenedTreeData: Item[][] ) { return flattenedTreeData.map((items) => { const autocompleteItem: AutocompleteItemType = { id: items[items.length - 1].id, pathLabel: items.map((item) => item.label).join(' / '), itemLabel: items[items.length - 1].label || items[items.length - 1].id, }; const tags = items.flatMap((item) => item.tags || []); if (tags.length) { autocompleteItem.tags = tags; } return autocompleteItem; }); } export function* getSingleChildren>( children: Item[] ): Generator { if (children.length === 1) { yield children[0].id; } for (const child of children) { if (child.items) { yield* getSingleChildren(child.items); } } } export function formatLargeNumber(x: string | number) { const string = x.toString(); // If number is converted to scientific notation return as is // because commas can't be added as the coefficient will be < 10 if (string.includes('e')) { return string; } const [integer, decimal] = x.toString().split('.'); const integerWithCommas = integer.replace(/\B(?=(\d{3})+(?!\d))/g, ','); return [integerWithCommas, decimal] .filter((el) => typeof el !== 'undefined') .join('.'); } export function formatBytesNumber(bytes: string | number, decimals = 0) { const bytesNumber = +bytes; if (!bytesNumber) { return '0 Bytes'; } const positiveDecimals = decimals < 0 ? 0 : decimals; const baseFactor = 1024; const units = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; const unitsIndex = Math.min( Math.floor(Math.log(bytesNumber) / Math.log(baseFactor)), units.length - 1 ); const number = (bytesNumber / baseFactor ** unitsIndex).toFixed( positiveDecimals ); const unit = units[unitsIndex]; return `${formatLargeNumber(parseFloat(number))} ${unit}`; } const reProtocol = /^(https?:)?(\/\/)?/; const reTrailingSlashes = /(\/+$)/; export const tidyUrlString = (url: string) => url.replace(reProtocol, '').replace(reTrailingSlashes, '');