const HOURS_IN_DAY = 8 ; interface Formatter { ( value , options ? ) : string ; } export function formatMeasure ( value , type , options ? ) { const formatter = getFormatter ( type ) ; return useFormatter ( value , formatter , options ) ; } function useFormatter ( value , formatter , options ? ) { return value !== undefined && value !== "" ? formatter ( value , options ) : "" ; } function getFormatter ( type ) { const FORMATTERS = { INT : intFormatter , SHORT_INT : shortIntFormatter , FLOAT : floatFormatter , PERCENT : percentFormatter , WORK_DUR : durationFormatter , SHORT_WORK_DUR : shortDurationFormatter , RATING : ratingFormatter , LEVEL : levelFormatter , MILLISEC : millisecondsFormatter , COMPARATOR : comparatorFormatter , } ; return FORMATTERS [ type ] || noFormatter ; } function numberFormatter ( value , minimumFractionDigits = 0 , maximumFractionDigits = minimumFractionDigits ) { const { format } = new Intl . NumberFormat ( "en-US" , { minimumFractionDigits , maximumFractionDigits , } ) ; return format ( value ) ; } function noFormatter ( value ) { return value . toString ( ) ; } function intFormatter ( value ) { return numberFormatter ( value ) ; } function shortIntFormatter ( value ) { if ( value >= 1e9 ) { return numberFormatter ( value / 1e9 ) + "G" ; } else if ( value >= 1e6 ) { return numberFormatter ( value / 1e6 ) + "M" ; } else if ( value >= 1e4 ) { return numberFormatter ( value / 1e3 ) + "k" ; } else if ( value >= 1e3 ) { return numberFormatter ( value / 1e3 , 0 , 1 ) + "k" ; } else { return numberFormatter ( value ) ; } } function floatFormatter ( value ) { return numberFormatter ( value , 1 , 5 ) ; } function percentFormatter ( value , options = { } ) { if ( typeof value === "string" ) { value = parseFloat ( value ) ; } if ( options . decimals ) { return numberFormatter ( value , options . decimals ) + "%" ; } return value === 100 ? "100%" : numberFormatter ( value , 1 ) + "%" ; } function ratingFormatter ( value ) { if ( typeof value === "string" ) { value = parseInt ( value , 10 ) ; } return String . fromCharCode ( 97 + value - 1 ) . toUpperCase ( ) ; } function levelFormatter ( value ) { const l10nKeys = { ERROR : "Failed" , WARN : "Warning" , OK : "Passed" , NONE : "None" , } ; const result = l10nKeys [ value . toUpperCase ( ) ] ; return result ? result : value ; } function comparatorFormatter ( value ) { const l10nKeys = { EQ : "&#61;" , GT : "&#62;" , LT : "&#60;" , NE : "&#8800;" , } ; const result = l10nKeys [ value . toUpperCase ( ) ] ; return result ? result : value ; } function millisecondsFormatter ( value ) { const ONE_SECOND = 1000 ; const ONE_MINUTE = 60 * ONE_SECOND ; if ( value >= ONE_MINUTE ) { const minutes = Math . round ( value / ONE_MINUTE ) ; return `${ minutes }min` ; } else if ( value >= ONE_SECOND ) { const seconds = Math . round ( value / ONE_SECOND ) ; return `${ seconds }s` ; } else { return `${ value }ms` ; } } function shouldDisplayDays ( days ) { return days > 0 ; } function shouldDisplayDaysInShortFormat ( days ) { return days > 0.9 ; } function shouldDisplayHours ( days , hours ) { return hours > 0 && days < 10 ; } function shouldDisplayHoursInShortFormat ( hours ) { return hours > 0.9 ; } function shouldDisplayMinutes ( days , hours , minutes ) { return minutes > 0 && hours < 10 && days === 0 ; } function addSpaceIfNeeded ( value ) { return value . length > 0 ? value + " " : value ; } function formatDuration ( isNegative , days , hours , minutes ) { let formatted = "" ; if ( shouldDisplayDays ( days ) ) { formatted += ( isNegative ? - 1 * days : days ) + "d" ; } if ( shouldDisplayHours ( days , hours ) ) { formatted = addSpaceIfNeeded ( formatted ) ; formatted += ( isNegative && formatted . length === 0 ? - 1 * hours : hours ) + "h" ; } if ( shouldDisplayMinutes ( days , hours , minutes ) ) { formatted = addSpaceIfNeeded ( formatted ) ; formatted += ( isNegative && formatted . length === 0 ? - 1 * minutes : minutes ) + "min" ; } return formatted ; } function formatDurationShort ( isNegative , days , hours , minutes ) { if ( shouldDisplayDaysInShortFormat ( days ) ) { const roundedDays = Math . round ( days ) ; const formattedDays = formatMeasure ( isNegative ? - 1 * roundedDays : roundedDays , "SHORT_INT" ) ; return formattedDays + "d" ; } if ( shouldDisplayHoursInShortFormat ( hours ) ) { const roundedHours = Math . round ( hours ) ; const formattedHours = formatMeasure ( isNegative ? - 1 * roundedHours : roundedHours , "SHORT_INT" ) ; return formattedHours + "h" ; } const formattedMinutes = formatMeasure ( isNegative ? - 1 * minutes : minutes , "SHORT_INT" ) ; return formattedMinutes + "min" ; } function durationFormatter ( value ) { if ( typeof value === "string" ) { value = parseInt ( value , 10 ) ; } if ( value === 0 ) { return "0" ; } const hoursInDay = HOURS_IN_DAY ; const isNegative = value < 0 ; const absValue = Math . abs ( value ) ; const days = Math . floor ( absValue / hoursInDay / 60 ) ; let remainingValue = absValue - days * hoursInDay * 60 ; const hours = Math . floor ( remainingValue / 60 ) ; remainingValue -= hours * 60 ; return formatDuration ( isNegative , days , hours , remainingValue ) ; } function shortDurationFormatter ( value ) { if ( typeof value === "string" ) { value = parseInt ( value , 10 ) ; } if ( value === 0 ) { return "0" ; } const hoursInDay = HOURS_IN_DAY ; const isNegative = value < 0 ; const absValue = Math . abs ( value ) ; const days = absValue / hoursInDay / 60 ; let remainingValue = absValue - Math . floor ( days ) * hoursInDay * 60 ; const hours = remainingValue / 60 ; remainingValue -= Math . floor ( hours ) * 60 ; return formatDurationShort ( isNegative , days , hours , remainingValue ) ; }