diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-03-16 18:18:33 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-03-16 18:18:33 +0000 |
commit | f64a639bcfa1fc2bc89ca7db268f594306edfd7c (patch) | |
tree | a2c3c2ebcc3b45e596949db485d6ed18ffaacfa1 /app/assets/javascripts/lib | |
parent | bfbc3e0d6583ea1a91f627528bedc3d65ba4b10f (diff) | |
download | gitlab-ce-f64a639bcfa1fc2bc89ca7db268f594306edfd7c.tar.gz |
Add latest changes from gitlab-org/gitlab@13-10-stable-eev13.10.0-rc40
Diffstat (limited to 'app/assets/javascripts/lib')
-rw-r--r-- | app/assets/javascripts/lib/chrome_84_icon_fix.js | 78 | ||||
-rw-r--r-- | app/assets/javascripts/lib/graphql.js | 3 | ||||
-rw-r--r-- | app/assets/javascripts/lib/utils/datetime_utility.js | 107 | ||||
-rw-r--r-- | app/assets/javascripts/lib/utils/experimentation.js | 3 | ||||
-rw-r--r-- | app/assets/javascripts/lib/utils/http_status.js | 1 | ||||
-rw-r--r-- | app/assets/javascripts/lib/utils/number_utils.js | 21 | ||||
-rw-r--r-- | app/assets/javascripts/lib/utils/select2_utils.js | 25 | ||||
-rw-r--r-- | app/assets/javascripts/lib/utils/text_markdown.js | 6 | ||||
-rw-r--r-- | app/assets/javascripts/lib/utils/unit_format/formatter_factory.js | 70 | ||||
-rw-r--r-- | app/assets/javascripts/lib/utils/unit_format/index.js | 342 | ||||
-rw-r--r-- | app/assets/javascripts/lib/utils/url_utility.js | 5 |
11 files changed, 389 insertions, 272 deletions
diff --git a/app/assets/javascripts/lib/chrome_84_icon_fix.js b/app/assets/javascripts/lib/chrome_84_icon_fix.js deleted file mode 100644 index 20fe9590ce3..00000000000 --- a/app/assets/javascripts/lib/chrome_84_icon_fix.js +++ /dev/null @@ -1,78 +0,0 @@ -import { debounce } from 'lodash'; - -/* - Chrome and Edge 84 have a bug relating to icon sprite svgs - https://bugs.chromium.org/p/chromium/issues/detail?id=1107442 - - If the SVG is loaded, under certain circumstances the icons are not - shown. We load our sprite icons with JS and add them to the body. - Then we iterate over all the `use` elements and replace their reference - to that svg which we added internally. In order to avoid id conflicts, - those are renamed with a unique prefix. - - We do that once the DOMContentLoaded fired and otherwise we use a - mutation observer to re-trigger this logic. - - In order to not have a big impact on performance or to cause flickering - of of content, - - 1. we only do it for each svg once - 2. we debounce the event handler and just do it in a requestIdleCallback - - Before we tried to do it with the library svg4everybody and it had a big - performance impact. See: - https://gitlab.com/gitlab-org/quality/performance/-/issues/312 - */ -document.addEventListener('DOMContentLoaded', async () => { - const GITLAB_SVG_PREFIX = 'chrome-issue-230433-gitlab-svgs'; - const FILE_ICON_PREFIX = 'chrome-issue-230433-file-icons'; - const SKIP_ATTRIBUTE = 'data-replaced-by-chrome-issue-230433'; - - const fixSVGs = () => { - requestIdleCallback(() => { - document.querySelectorAll(`use:not([${SKIP_ATTRIBUTE}])`).forEach((use) => { - const href = use?.getAttribute('href') ?? use?.getAttribute('xlink:href') ?? ''; - - if (href.includes(window.gon.sprite_icons)) { - use.removeAttribute('xlink:href'); - use.setAttribute('href', `#${GITLAB_SVG_PREFIX}-${href.split('#')[1]}`); - } else if (href.includes(window.gon.sprite_file_icons)) { - use.removeAttribute('xlink:href'); - use.setAttribute('href', `#${FILE_ICON_PREFIX}-${href.split('#')[1]}`); - } - - use.setAttribute(SKIP_ATTRIBUTE, 'true'); - }); - }); - }; - - const watchForNewSVGs = () => { - const observer = new MutationObserver(debounce(fixSVGs, 200)); - observer.observe(document.querySelector('body'), { - childList: true, - attributes: false, - subtree: true, - }); - }; - - const retrieveIconSprites = async (url, prefix) => { - const div = document.createElement('div'); - div.classList.add('hidden'); - const result = await fetch(url); - div.innerHTML = await result.text(); - div.querySelectorAll('[id]').forEach((node) => { - node.setAttribute('id', `${prefix}-${node.getAttribute('id')}`); - }); - document.body.append(div); - }; - - if (window.gon && window.gon.sprite_icons) { - await retrieveIconSprites(window.gon.sprite_icons, GITLAB_SVG_PREFIX); - if (window.gon.sprite_file_icons) { - await retrieveIconSprites(window.gon.sprite_file_icons, FILE_ICON_PREFIX); - } - - fixSVGs(); - watchForNewSVGs(); - } -}); diff --git a/app/assets/javascripts/lib/graphql.js b/app/assets/javascripts/lib/graphql.js index bda5550a9f4..e090f9f6e8c 100644 --- a/app/assets/javascripts/lib/graphql.js +++ b/app/assets/javascripts/lib/graphql.js @@ -2,6 +2,7 @@ import { InMemoryCache } from 'apollo-cache-inmemory'; import { ApolloClient } from 'apollo-client'; import { ApolloLink } from 'apollo-link'; import { BatchHttpLink } from 'apollo-link-batch-http'; +import { createHttpLink } from 'apollo-link-http'; import { createUploadLink } from 'apollo-upload-client'; import { StartupJSLink } from '~/lib/utils/apollo_startup_js_link'; import csrf from '~/lib/utils/csrf'; @@ -48,7 +49,7 @@ export default (resolvers = {}, config = {}) => { const uploadsLink = ApolloLink.split( (operation) => operation.getContext().hasUpload || operation.getContext().isSingleRequest, createUploadLink(httpOptions), - new BatchHttpLink(httpOptions), + config.useGet ? createHttpLink(httpOptions) : new BatchHttpLink(httpOptions), ); const performanceBarLink = new ApolloLink((operation, forward) => { diff --git a/app/assets/javascripts/lib/utils/datetime_utility.js b/app/assets/javascripts/lib/utils/datetime_utility.js index 38b3b26dc44..145b419f8f0 100644 --- a/app/assets/javascripts/lib/utils/datetime_utility.js +++ b/app/assets/javascripts/lib/utils/datetime_utility.js @@ -769,6 +769,19 @@ export const nMonthsAfter = (date, numberOfMonths, { utc = false } = {}) => { }; /** + * Returns the date `n` years after the date provided. + * + * @param {Date} date the initial date + * @param {Number} numberOfYears number of years after + * @return {Date} A `Date` object `n` years after the provided `Date` + */ +export const nYearsAfter = (date, numberOfYears) => { + const clone = newDate(date); + clone.setFullYear(clone.getFullYear() + numberOfYears); + return clone; +}; + +/** * Returns the date `n` months before the date provided * * @param {Date} date the initial date @@ -993,6 +1006,78 @@ export const isToday = (date) => { }; /** + * Checks whether the date is in the past. + * + * @param {Date} date + * @return {Boolean} Returns true if the date falls before today, otherwise false. + */ +export const isInPast = (date) => !isToday(date) && differenceInMilliseconds(date, Date.now()) > 0; + +/** + * Checks whether the date is in the future. + * . + * @param {Date} date + * @return {Boolean} Returns true if the date falls after today, otherwise false. + */ +export const isInFuture = (date) => + !isToday(date) && differenceInMilliseconds(Date.now(), date) > 0; + +/** + * Checks whether dateA falls before dateB. + * + * @param {Date} dateA + * @param {Date} dateB + * @return {Boolean} Returns true if dateA falls before dateB, otherwise false + */ +export const fallsBefore = (dateA, dateB) => differenceInMilliseconds(dateA, dateB) > 0; + +/** + * Removes the time component of the date. + * + * @param {Date} date + * @return {Date} Returns a clone of the date with the time set to midnight + */ +export const removeTime = (date) => { + const clone = newDate(date); + clone.setHours(0, 0, 0, 0); + return clone; +}; + +/** + * Calculates the time remaining from today in words in the format + * `n days/weeks/months/years remaining`. + * + * @param {Date} date A date in future + * @return {String} The time remaining in the format `n days/weeks/months/years remaining` + */ +export const getTimeRemainingInWords = (date) => { + const today = removeTime(new Date()); + const dateInFuture = removeTime(date); + + const oneWeekFromNow = nWeeksAfter(today, 1); + const oneMonthFromNow = nMonthsAfter(today, 1); + const oneYearFromNow = nYearsAfter(today, 1); + + if (fallsBefore(dateInFuture, oneWeekFromNow)) { + const days = getDayDifference(today, dateInFuture); + return n__('1 day remaining', '%d days remaining', days); + } + + if (fallsBefore(dateInFuture, oneMonthFromNow)) { + const weeks = Math.floor(getDayDifference(today, dateInFuture) / 7); + return n__('1 week remaining', '%d weeks remaining', weeks); + } + + if (fallsBefore(dateInFuture, oneYearFromNow)) { + const months = differenceInMonths(today, dateInFuture); + return n__('1 month remaining', '%d months remaining', months); + } + + const years = dateInFuture.getFullYear() - today.getFullYear(); + return n__('1 year remaining', '%d years remaining', years); +}; + +/** * Returns the start of the provided day * * @param {Object} [options={}] Additional options for this calculation @@ -1010,3 +1095,25 @@ export const getStartOfDay = (date, { utc = false } = {}) => { return new Date(cloneValue); }; + +/** + * Returns the start of the current week against the provide date + * + * @param {Date} date The current date instance to calculate against + * @param {Object} [options={}] Additional options for this calculation + * @param {boolean} [options.utc=false] Performs the calculation using UTC time. + * If `true`, the time returned will be midnight UTC. If `false` (the default) + * the time returned will be midnight in the user's local time. + * + * @returns {Date} A new `Date` object that represents the start of the current week + * of the provided date + */ +export const getStartOfWeek = (date, { utc = false } = {}) => { + const cloneValue = utc + ? new Date(date.setUTCHours(0, 0, 0, 0)) + : new Date(date.setHours(0, 0, 0, 0)); + + const diff = cloneValue.getDate() - cloneValue.getDay() + (cloneValue.getDay() === 0 ? -6 : 1); + + return new Date(date.setDate(diff)); +}; diff --git a/app/assets/javascripts/lib/utils/experimentation.js b/app/assets/javascripts/lib/utils/experimentation.js deleted file mode 100644 index 555e76055e0..00000000000 --- a/app/assets/javascripts/lib/utils/experimentation.js +++ /dev/null @@ -1,3 +0,0 @@ -export function isExperimentEnabled(experimentKey) { - return Boolean(window.gon?.experiments?.[experimentKey]); -} diff --git a/app/assets/javascripts/lib/utils/http_status.js b/app/assets/javascripts/lib/utils/http_status.js index 06529f06a66..6b9be34235b 100644 --- a/app/assets/javascripts/lib/utils/http_status.js +++ b/app/assets/javascripts/lib/utils/http_status.js @@ -19,6 +19,7 @@ const httpStatusCodes = { UNAUTHORIZED: 401, FORBIDDEN: 403, NOT_FOUND: 404, + METHOD_NOT_ALLOWED: 405, CONFLICT: 409, GONE: 410, UNPROCESSABLE_ENTITY: 422, diff --git a/app/assets/javascripts/lib/utils/number_utils.js b/app/assets/javascripts/lib/utils/number_utils.js index 0f29f538b07..63feb6f9b1d 100644 --- a/app/assets/javascripts/lib/utils/number_utils.js +++ b/app/assets/javascripts/lib/utils/number_utils.js @@ -150,3 +150,24 @@ export const formattedChangeInPercent = (firstY, lastY, { nonFiniteResult = '-' return `${change >= 0 ? '+' : ''}${change}%`; }; + +/** + * Checks whether a value is numerical in nature by converting it using parseInt + * + * Example outcomes: + * - isNumeric(100) = true + * - isNumeric('100') = true + * - isNumeric(1.0) = true + * - isNumeric('1.0') = true + * - isNumeric('abc100') = false + * - isNumeric('abc') = false + * - isNumeric(true) = false + * - isNumeric(undefined) = false + * - isNumeric(null) = false + * + * @param value + * @returns {boolean} + */ +export const isNumeric = (value) => { + return !Number.isNaN(parseInt(value, 10)); +}; diff --git a/app/assets/javascripts/lib/utils/select2_utils.js b/app/assets/javascripts/lib/utils/select2_utils.js new file mode 100644 index 00000000000..03c0e608b79 --- /dev/null +++ b/app/assets/javascripts/lib/utils/select2_utils.js @@ -0,0 +1,25 @@ +import axios from './axios_utils'; +import { normalizeHeaders, parseIntPagination } from './common_utils'; + +// This is used in the select2 config to replace jQuery.ajax with axios +export const select2AxiosTransport = (params) => { + axios({ + method: params.type?.toLowerCase() || 'get', + url: params.url, + params: params.data, + }) + .then((res) => { + const results = res.data || []; + const headers = normalizeHeaders(res.headers); + const pagination = parseIntPagination(headers); + const more = pagination.nextPage > pagination.page; + + params.success({ + results, + pagination: { + more, + }, + }); + }) + .catch(params.error); +}; diff --git a/app/assets/javascripts/lib/utils/text_markdown.js b/app/assets/javascripts/lib/utils/text_markdown.js index 5e66aa05218..345dfaf895b 100644 --- a/app/assets/javascripts/lib/utils/text_markdown.js +++ b/app/assets/javascripts/lib/utils/text_markdown.js @@ -283,9 +283,9 @@ function updateText({ textArea, tag, cursorOffset, blockTag, wrap, select, tagCo /* eslint-disable @gitlab/require-i18n-strings */ export function keypressNoteText(e) { - if (this.selectionStart === this.selectionEnd) { - return; - } + if (!gon.markdown_surround_selection) return; + if (this.selectionStart === this.selectionEnd) return; + const keys = { '*': '**{text}**', // wraps with bold character _: '_{text}_', // wraps with italic character diff --git a/app/assets/javascripts/lib/utils/unit_format/formatter_factory.js b/app/assets/javascripts/lib/utils/unit_format/formatter_factory.js index 15f9512fe92..418cc69bf5a 100644 --- a/app/assets/javascripts/lib/utils/unit_format/formatter_factory.js +++ b/app/assets/javascripts/lib/utils/unit_format/formatter_factory.js @@ -1,39 +1,30 @@ +import { formatNumber } from '~/locale'; + /** - * Formats a number as string using `toLocaleString`. + * Formats a number as a string using `toLocaleString`. * * @param {Number} number to be converted - * @param {params} Parameters - * @param {params.fractionDigits} Number of decimal digits - * to display, defaults to using `toLocaleString` defaults. - * @param {params.maxLength} Max output char lenght at the + * + * @param {options.maxCharLength} Max output char length at the * expense of precision, if the output is longer than this, * the formatter switches to using exponential notation. - * @param {params.factor} Value is multiplied by this factor, - * useful for value normalization. - * @returns Formatted value + * + * @param {options.valueFactor} Value is multiplied by this factor, + * useful for value normalization or to alter orders of magnitude. + * + * @param {options} Other options to be passed to + * `formatNumber` such as `valueFactor`, `unit` and `style`. + * */ -function formatNumber( - value, - { fractionDigits = undefined, valueFactor = 1, style = undefined, maxLength = undefined }, -) { - if (value === null) { - return ''; - } - - const locale = document.documentElement.lang || undefined; - const num = value * valueFactor; - const formatted = num.toLocaleString(locale, { - minimumFractionDigits: fractionDigits, - maximumFractionDigits: fractionDigits, - style, - }); +const formatNumberNormalized = (value, { maxCharLength, valueFactor = 1, ...options }) => { + const formatted = formatNumber(value * valueFactor, options); - if (maxLength !== undefined && formatted.length > maxLength) { + if (maxCharLength !== undefined && formatted.length > maxCharLength) { // 123456 becomes 1.23e+8 - return num.toExponential(2); + return value.toExponential(2); } return formatted; -} +}; /** * Formats a number as a string scaling it up according to units. @@ -76,7 +67,10 @@ const scaledFormatter = (units, unitFactor = 1000) => { const unit = units[scale]; - return `${formatNumber(num, { fractionDigits })}${unit}`; + return `${formatNumberNormalized(num, { + maximumFractionDigits: fractionDigits, + minimumFractionDigits: fractionDigits, + })}${unit}`; }; }; @@ -84,8 +78,14 @@ const scaledFormatter = (units, unitFactor = 1000) => { * Returns a function that formats a number as a string. */ export const numberFormatter = (style = 'decimal', valueFactor = 1) => { - return (value, fractionDigits, maxLength) => { - return `${formatNumber(value, { fractionDigits, maxLength, valueFactor, style })}`; + return (value, fractionDigits, maxCharLength) => { + return `${formatNumberNormalized(value, { + maxCharLength, + valueFactor, + style, + maximumFractionDigits: fractionDigits, + minimumFractionDigits: fractionDigits, + })}`; }; }; @@ -93,9 +93,15 @@ export const numberFormatter = (style = 'decimal', valueFactor = 1) => { * Returns a function that formats a number as a string with a suffix. */ export const suffixFormatter = (unit = '', valueFactor = 1) => { - return (value, fractionDigits, maxLength) => { - const length = maxLength !== undefined ? maxLength - unit.length : undefined; - return `${formatNumber(value, { fractionDigits, maxLength: length, valueFactor })}${unit}`; + return (value, fractionDigits, maxCharLength) => { + const length = maxCharLength !== undefined ? maxCharLength - unit.length : undefined; + + return `${formatNumberNormalized(value, { + maxCharLength: length, + valueFactor, + maximumFractionDigits: fractionDigits, + minimumFractionDigits: fractionDigits, + })}${unit}`; }; }; diff --git a/app/assets/javascripts/lib/utils/unit_format/index.js b/app/assets/javascripts/lib/utils/unit_format/index.js index 9f979f7ea4b..bc82c6aa74d 100644 --- a/app/assets/javascripts/lib/utils/unit_format/index.js +++ b/app/assets/javascripts/lib/utils/unit_format/index.js @@ -46,227 +46,261 @@ export const SUPPORTED_FORMATS = { }; /** - * Returns a function that formats number to different units - * @param {String} format - Format to use, must be one of the SUPPORTED_FORMATS. Defaults to engineering notation. + * Returns a function that formats number to different units. * + * Used for dynamic formatting, for more convenience, use the functions below. * + * @param {String} format - Format to use, must be one of the SUPPORTED_FORMATS. Defaults to engineering notation. */ export const getFormatter = (format = SUPPORTED_FORMATS.engineering) => { // Number - if (format === SUPPORTED_FORMATS.number) { - /** - * Formats a number - * - * @function - * @param {Number} value - Number to format - * @param {Number} fractionDigits - precision decimals - * @param {Number} maxLength - Max length of formatted number - * if length is exceeded, exponential format is used. - */ return numberFormatter(); } if (format === SUPPORTED_FORMATS.percent) { - /** - * Formats a percentge (0 - 1) - * - * @function - * @param {Number} value - Number to format, `1` is rendered as `100%` - * @param {Number} fractionDigits - number of precision decimals - * @param {Number} maxLength - Max length of formatted number - * if length is exceeded, exponential format is used. - */ return numberFormatter('percent'); } if (format === SUPPORTED_FORMATS.percentHundred) { - /** - * Formats a percentge (0 to 100) - * - * @function - * @param {Number} value - Number to format, `100` is rendered as `100%` - * @param {Number} fractionDigits - number of precision decimals - * @param {Number} maxLength - Max length of formatted number - * if length is exceeded, exponential format is used. - */ return numberFormatter('percent', 1 / 100); } // Durations - if (format === SUPPORTED_FORMATS.seconds) { - /** - * Formats a number of seconds - * - * @function - * @param {Number} value - Number to format, `1` is rendered as `1s` - * @param {Number} fractionDigits - number of precision decimals - * @param {Number} maxLength - Max length of formatted number - * if length is exceeded, exponential format is used. - */ return suffixFormatter(s__('Units|s')); } if (format === SUPPORTED_FORMATS.milliseconds) { - /** - * Formats a number of milliseconds with ms as units - * - * @function - * @param {Number} value - Number to format, `1` is formatted as `1ms` - * @param {Number} fractionDigits - number of precision decimals - * @param {Number} maxLength - Max length of formatted number - * if length is exceeded, exponential format is used. - */ return suffixFormatter(s__('Units|ms')); } // Digital (Metric) - if (format === SUPPORTED_FORMATS.decimalBytes) { - /** - * Formats a number of bytes scaled up to larger digital - * units for larger numbers. - * - * @function - * @param {Number} value - Number to format, `1` is formatted as `1B` - * @param {Number} fractionDigits - number of precision decimals - */ return scaledSIFormatter('B'); } if (format === SUPPORTED_FORMATS.kilobytes) { - /** - * Formats a number of kilobytes scaled up to larger digital - * units for larger numbers. - * - * @function - * @param {Number} value - Number to format, `1` is formatted as `1kB` - * @param {Number} fractionDigits - number of precision decimals - */ return scaledSIFormatter('B', 1); } if (format === SUPPORTED_FORMATS.megabytes) { - /** - * Formats a number of megabytes scaled up to larger digital - * units for larger numbers. - * - * @function - * @param {Number} value - Number to format, `1` is formatted as `1MB` - * @param {Number} fractionDigits - number of precision decimals - */ return scaledSIFormatter('B', 2); } if (format === SUPPORTED_FORMATS.gigabytes) { - /** - * Formats a number of gigabytes scaled up to larger digital - * units for larger numbers. - * - * @function - * @param {Number} value - Number to format, `1` is formatted as `1GB` - * @param {Number} fractionDigits - number of precision decimals - */ return scaledSIFormatter('B', 3); } if (format === SUPPORTED_FORMATS.terabytes) { - /** - * Formats a number of terabytes scaled up to larger digital - * units for larger numbers. - * - * @function - * @param {Number} value - Number to format, `1` is formatted as `1GB` - * @param {Number} fractionDigits - number of precision decimals - */ return scaledSIFormatter('B', 4); } if (format === SUPPORTED_FORMATS.petabytes) { - /** - * Formats a number of petabytes scaled up to larger digital - * units for larger numbers. - * - * @function - * @param {Number} value - Number to format, `1` is formatted as `1PB` - * @param {Number} fractionDigits - number of precision decimals - */ return scaledSIFormatter('B', 5); } // Digital (IEC) - if (format === SUPPORTED_FORMATS.bytes) { - /** - * Formats a number of bytes scaled up to larger digital - * units for larger numbers. - * - * @function - * @param {Number} value - Number to format, `1` is formatted as `1B` - * @param {Number} fractionDigits - number of precision decimals - */ return scaledBinaryFormatter('B'); } if (format === SUPPORTED_FORMATS.kibibytes) { - /** - * Formats a number of kilobytes scaled up to larger digital - * units for larger numbers. - * - * @function - * @param {Number} value - Number to format, `1` is formatted as `1kB` - * @param {Number} fractionDigits - number of precision decimals - */ return scaledBinaryFormatter('B', 1); } if (format === SUPPORTED_FORMATS.mebibytes) { - /** - * Formats a number of megabytes scaled up to larger digital - * units for larger numbers. - * - * @function - * @param {Number} value - Number to format, `1` is formatted as `1MB` - * @param {Number} fractionDigits - number of precision decimals - */ return scaledBinaryFormatter('B', 2); } if (format === SUPPORTED_FORMATS.gibibytes) { - /** - * Formats a number of gigabytes scaled up to larger digital - * units for larger numbers. - * - * @function - * @param {Number} value - Number to format, `1` is formatted as `1GB` - * @param {Number} fractionDigits - number of precision decimals - */ return scaledBinaryFormatter('B', 3); } if (format === SUPPORTED_FORMATS.tebibytes) { - /** - * Formats a number of terabytes scaled up to larger digital - * units for larger numbers. - * - * @function - * @param {Number} value - Number to format, `1` is formatted as `1GB` - * @param {Number} fractionDigits - number of precision decimals - */ return scaledBinaryFormatter('B', 4); } if (format === SUPPORTED_FORMATS.pebibytes) { - /** - * Formats a number of petabytes scaled up to larger digital - * units for larger numbers. - * - * @function - * @param {Number} value - Number to format, `1` is formatted as `1PB` - * @param {Number} fractionDigits - number of precision decimals - */ return scaledBinaryFormatter('B', 5); } + // Default if (format === SUPPORTED_FORMATS.engineering) { - /** - * Formats via engineering notation - * - * @function - * @param {Number} value - Value to format - * @param {Number} fractionDigits - precision decimals - Defaults to 2 - */ return engineeringNotation; } // Fail so client library addresses issue throw TypeError(`${format} is not a valid number format`); }; + +/** + * Formats a number + * + * @function + * @param {Number} value - Number to format + * @param {Number} fractionDigits - precision decimals + * @param {Number} maxLength - Max length of formatted number + * if length is exceeded, exponential format is used. + */ +export const number = getFormatter(SUPPORTED_FORMATS.number); + +/** + * Formats a percentage (0 - 1) + * + * @function + * @param {Number} value - Number to format, `1` is rendered as `100%` + * @param {Number} fractionDigits - number of precision decimals + * @param {Number} maxLength - Max length of formatted number + * if length is exceeded, exponential format is used. + */ +export const percent = getFormatter(SUPPORTED_FORMATS.percent); + +/** + * Formats a percentage (0 to 100) + * + * @function + * @param {Number} value - Number to format, `100` is rendered as `100%` + * @param {Number} fractionDigits - number of precision decimals + * @param {Number} maxLength - Max length of formatted number + * if length is exceeded, exponential format is used. + */ +export const percentHundred = getFormatter(SUPPORTED_FORMATS.percentHundred); + +/** + * Formats a number of seconds + * + * @function + * @param {Number} value - Number to format, `1` is rendered as `1s` + * @param {Number} fractionDigits - number of precision decimals + * @param {Number} maxLength - Max length of formatted number + * if length is exceeded, exponential format is used. + */ +export const seconds = getFormatter(SUPPORTED_FORMATS.seconds); + +/** + * Formats a number of milliseconds with ms as units + * + * @function + * @param {Number} value - Number to format, `1` is formatted as `1ms` + * @param {Number} fractionDigits - number of precision decimals + * @param {Number} maxLength - Max length of formatted number + * if length is exceeded, exponential format is used. + */ +export const milliseconds = getFormatter(SUPPORTED_FORMATS.milliseconds); + +/** + * Formats a number of bytes scaled up to larger digital + * units for larger numbers. + * + * @function + * @param {Number} value - Number to format, `1` is formatted as `1B` + * @param {Number} fractionDigits - number of precision decimals + */ +export const decimalBytes = getFormatter(SUPPORTED_FORMATS.decimalBytes); + +/** + * Formats a number of kilobytes scaled up to larger digital + * units for larger numbers. + * + * @function + * @param {Number} value - Number to format, `1` is formatted as `1kB` + * @param {Number} fractionDigits - number of precision decimals + */ +export const kilobytes = getFormatter(SUPPORTED_FORMATS.kilobytes); + +/** + * Formats a number of megabytes scaled up to larger digital + * units for larger numbers. + * + * @function + * @param {Number} value - Number to format, `1` is formatted as `1MB` + * @param {Number} fractionDigits - number of precision decimals + */ +export const megabytes = getFormatter(SUPPORTED_FORMATS.megabytes); + +/** + * Formats a number of gigabytes scaled up to larger digital + * units for larger numbers. + * + * @function + * @param {Number} value - Number to format, `1` is formatted as `1GB` + * @param {Number} fractionDigits - number of precision decimals + */ +export const gigabytes = getFormatter(SUPPORTED_FORMATS.gigabytes); + +/** + * Formats a number of terabytes scaled up to larger digital + * units for larger numbers. + * + * @function + * @param {Number} value - Number to format, `1` is formatted as `1GB` + * @param {Number} fractionDigits - number of precision decimals + */ +export const terabytes = getFormatter(SUPPORTED_FORMATS.terabytes); + +/** + * Formats a number of petabytes scaled up to larger digital + * units for larger numbers. + * + * @function + * @param {Number} value - Number to format, `1` is formatted as `1PB` + * @param {Number} fractionDigits - number of precision decimals + */ +export const petabytes = getFormatter(SUPPORTED_FORMATS.petabytes); + +/** + * Formats a number of bytes scaled up to larger digital + * units for larger numbers. + * + * @function + * @param {Number} value - Number to format, `1` is formatted as `1B` + * @param {Number} fractionDigits - number of precision decimals + */ +export const bytes = getFormatter(SUPPORTED_FORMATS.bytes); + +/** + * Formats a number of kilobytes scaled up to larger digital + * units for larger numbers. + * + * @function + * @param {Number} value - Number to format, `1` is formatted as `1kB` + * @param {Number} fractionDigits - number of precision decimals + */ +export const kibibytes = getFormatter(SUPPORTED_FORMATS.kibibytes); + +/** + * Formats a number of megabytes scaled up to larger digital + * units for larger numbers. + * + * @function + * @param {Number} value - Number to format, `1` is formatted as `1MB` + * @param {Number} fractionDigits - number of precision decimals + */ +export const mebibytes = getFormatter(SUPPORTED_FORMATS.mebibytes); + +/** + * Formats a number of gigabytes scaled up to larger digital + * units for larger numbers. + * + * @function + * @param {Number} value - Number to format, `1` is formatted as `1GB` + * @param {Number} fractionDigits - number of precision decimals + */ +export const gibibytes = getFormatter(SUPPORTED_FORMATS.gibibytes); + +/** + * Formats a number of terabytes scaled up to larger digital + * units for larger numbers. + * + * @function + * @param {Number} value - Number to format, `1` is formatted as `1GB` + * @param {Number} fractionDigits - number of precision decimals + */ +export const tebibytes = getFormatter(SUPPORTED_FORMATS.tebibytes); + +/** + * Formats a number of petabytes scaled up to larger digital + * units for larger numbers. + * + * @function + * @param {Number} value - Number to format, `1` is formatted as `1PB` + * @param {Number} fractionDigits - number of precision decimals + */ +export const pebibytes = getFormatter(SUPPORTED_FORMATS.pebibytes); + +/** + * Formats via engineering notation + * + * @function + * @param {Number} value - Value to format + * @param {Number} fractionDigits - precision decimals - Defaults to 2 + */ +export const engineering = getFormatter(); diff --git a/app/assets/javascripts/lib/utils/url_utility.js b/app/assets/javascripts/lib/utils/url_utility.js index cc2cf787a8f..5b3aa3cf9dc 100644 --- a/app/assets/javascripts/lib/utils/url_utility.js +++ b/app/assets/javascripts/lib/utils/url_utility.js @@ -473,6 +473,7 @@ export const setUrlParams = ( url = window.location.href, clearParams = false, railsArraySyntax = false, + decodeParams = false, ) => { const urlObj = new URL(url); const queryString = urlObj.search; @@ -495,7 +496,9 @@ export const setUrlParams = ( } }); - urlObj.search = searchParams.toString(); + urlObj.search = decodeParams + ? decodeURIComponent(searchParams.toString()) + : searchParams.toString(); return urlObj.toString(); }; |