diff options
Diffstat (limited to 'app/assets/javascripts/lib/utils')
-rw-r--r-- | app/assets/javascripts/lib/utils/common_utils.js | 14 | ||||
-rw-r--r-- | app/assets/javascripts/lib/utils/constants.js | 8 | ||||
-rw-r--r-- | app/assets/javascripts/lib/utils/datetime_range.js | 15 | ||||
-rw-r--r-- | app/assets/javascripts/lib/utils/dom_utils.js | 13 | ||||
-rw-r--r-- | app/assets/javascripts/lib/utils/text_utility.js | 9 | ||||
-rw-r--r-- | app/assets/javascripts/lib/utils/url_utility.js | 17 |
6 files changed, 64 insertions, 12 deletions
diff --git a/app/assets/javascripts/lib/utils/common_utils.js b/app/assets/javascripts/lib/utils/common_utils.js index 4a48852159a..a60748215ab 100644 --- a/app/assets/javascripts/lib/utils/common_utils.js +++ b/app/assets/javascripts/lib/utils/common_utils.js @@ -31,7 +31,7 @@ export const getProjectSlug = () => { }; export const getGroupSlug = () => { - if (isInGroupsPage()) { + if (isInProjectPage() || isInGroupsPage()) { return $('body').data('group'); } return null; @@ -244,22 +244,28 @@ export const contentTop = () => { ); }; -export const scrollToElement = element => { +export const scrollToElement = (element, options = {}) => { let $el = element; if (!(element instanceof $)) { $el = $(element); } const { top } = $el.offset(); + const { offset = 0 } = options; // eslint-disable-next-line no-jquery/no-animate return $('body, html').animate( { - scrollTop: top - contentTop(), + scrollTop: top - contentTop() + offset, }, 200, ); }; +export const scrollToElementWithContext = element => { + const offsetMultiplier = -0.1; + return scrollToElement(element, { offset: window.innerHeight * offsetMultiplier }); +}; + /** * Returns a function that can only be invoked once between * each browser screen repaint. @@ -718,6 +724,8 @@ export const convertObjectProps = (conversionFunction, obj = {}, options = {}) = } else { acc[conversionFunction(prop)] = convertObjectProps(conversionFunction, val, options); } + } else if (isObjParameterArray) { + acc[prop] = val; } else { acc[conversionFunction(prop)] = val; } diff --git a/app/assets/javascripts/lib/utils/constants.js b/app/assets/javascripts/lib/utils/constants.js index 9a61003ef30..eb6c9bf7eb6 100644 --- a/app/assets/javascripts/lib/utils/constants.js +++ b/app/assets/javascripts/lib/utils/constants.js @@ -1,2 +1,10 @@ export const BYTES_IN_KIB = 1024; export const HIDDEN_CLASS = 'hidden'; + +export const DATETIME_RANGE_TYPES = { + fixed: 'fixed', + anchored: 'anchored', + rolling: 'rolling', + open: 'open', + invalid: 'invalid', +}; diff --git a/app/assets/javascripts/lib/utils/datetime_range.js b/app/assets/javascripts/lib/utils/datetime_range.js index 9275b9e74e1..8efbcb89607 100644 --- a/app/assets/javascripts/lib/utils/datetime_range.js +++ b/app/assets/javascripts/lib/utils/datetime_range.js @@ -1,5 +1,6 @@ import dateformat from 'dateformat'; import { pick, omit, isEqual, isEmpty } from 'lodash'; +import { DATETIME_RANGE_TYPES } from './constants'; import { secondsToMilliseconds } from './datetime_utility'; const MINIMUM_DATE = new Date(0); @@ -153,18 +154,22 @@ export function getRangeType(range) { const { start, end, anchor, duration } = range; if ((start || end) && !anchor && !duration) { - return isValidDateString(start) && isValidDateString(end) ? 'fixed' : 'invalid'; + return isValidDateString(start) && isValidDateString(end) + ? DATETIME_RANGE_TYPES.fixed + : DATETIME_RANGE_TYPES.invalid; } if (anchor && duration) { - return isValidDateString(anchor) && isValidDuration(duration) ? 'anchored' : 'invalid'; + return isValidDateString(anchor) && isValidDuration(duration) + ? DATETIME_RANGE_TYPES.anchored + : DATETIME_RANGE_TYPES.invalid; } if (duration && !anchor) { - return isValidDuration(duration) ? 'rolling' : 'invalid'; + return isValidDuration(duration) ? DATETIME_RANGE_TYPES.rolling : DATETIME_RANGE_TYPES.invalid; } if (anchor && !duration) { - return isValidDateString(anchor) ? 'open' : 'invalid'; + return isValidDateString(anchor) ? DATETIME_RANGE_TYPES.open : DATETIME_RANGE_TYPES.invalid; } - return 'invalid'; + return DATETIME_RANGE_TYPES.invalid; } /** diff --git a/app/assets/javascripts/lib/utils/dom_utils.js b/app/assets/javascripts/lib/utils/dom_utils.js index 7933c234384..8fa235f8afb 100644 --- a/app/assets/javascripts/lib/utils/dom_utils.js +++ b/app/assets/javascripts/lib/utils/dom_utils.js @@ -12,3 +12,16 @@ export const canScrollUp = ({ scrollTop }, margin = 0) => scrollTop > margin; export const canScrollDown = ({ scrollTop, offsetHeight, scrollHeight }, margin = 0) => scrollTop + offsetHeight < scrollHeight - margin; + +export const toggleContainerClasses = (containerEl, classList) => { + if (containerEl) { + // eslint-disable-next-line array-callback-return + Object.entries(classList).map(([key, value]) => { + if (value) { + containerEl.classList.add(key); + } else { + containerEl.classList.remove(key); + } + }); + } +}; diff --git a/app/assets/javascripts/lib/utils/text_utility.js b/app/assets/javascripts/lib/utils/text_utility.js index 86714471823..be3fe1ed620 100644 --- a/app/assets/javascripts/lib/utils/text_utility.js +++ b/app/assets/javascripts/lib/utils/text_utility.js @@ -90,6 +90,13 @@ export const truncatePathMiddleToLength = (text, maxWidth) => { while (returnText.length >= maxWidth) { const textSplit = returnText.split('/').filter(s => s !== ELLIPSIS_CHAR); + + if (textSplit.length === 0) { + // There are n - 1 path separators for n segments, so 2n - 1 <= maxWidth + const maxSegments = Math.floor((maxWidth + 1) / 2); + return new Array(maxSegments).fill(ELLIPSIS_CHAR).join('/'); + } + const middleIndex = Math.floor(textSplit.length / 2); returnText = textSplit @@ -168,7 +175,7 @@ export const convertToCamelCase = string => * @param {*} string */ export const convertToSnakeCase = string => - slugifyWithUnderscore(string.match(/([a-zA-Z][^A-Z]*)/g).join(' ')); + slugifyWithUnderscore((string.match(/([a-zA-Z][^A-Z]*)/g) || [string]).join(' ')); /** * Converts a sentence to lower case from the second word onwards diff --git a/app/assets/javascripts/lib/utils/url_utility.js b/app/assets/javascripts/lib/utils/url_utility.js index 966e6d42b80..0472b8cf51f 100644 --- a/app/assets/javascripts/lib/utils/url_utility.js +++ b/app/assets/javascripts/lib/utils/url_utility.js @@ -109,9 +109,10 @@ export function mergeUrlParams(params, url) { * * @param {string[]} params - the query param names to remove * @param {string} [url=windowLocation().href] - url from which the query param will be removed + * @param {boolean} skipEncoding - set to true when the url does not require encoding * @returns {string} A copy of the original url but without the query param */ -export function removeParams(params, url = window.location.href) { +export function removeParams(params, url = window.location.href, skipEncoding = false) { const [rootAndQuery, fragment] = url.split('#'); const [root, query] = rootAndQuery.split('?'); @@ -119,12 +120,13 @@ export function removeParams(params, url = window.location.href) { return url; } - const encodedParams = params.map(param => encodeURIComponent(param)); + const removableParams = skipEncoding ? params : params.map(param => encodeURIComponent(param)); + const updatedQuery = query .split('&') .filter(paramPair => { const [foundParam] = paramPair.split('='); - return encodedParams.indexOf(foundParam) < 0; + return removableParams.indexOf(foundParam) < 0; }) .join('&'); @@ -242,6 +244,15 @@ export function isRootRelative(url) { } /** + * Returns true if url is a base64 data URL + * + * @param {String} url + */ +export function isBase64DataUrl(url) { + return /^data:[.\w+-]+\/[.\w+-]+;base64,/.test(url); +} + +/** * Returns true if url is an absolute or root-relative URL * * @param {String} url |