summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/lib
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/lib')
-rw-r--r--app/assets/javascripts/lib/graphql.js6
-rw-r--r--app/assets/javascripts/lib/utils/chart_utils.js17
-rw-r--r--app/assets/javascripts/lib/utils/datetime_utility.js58
-rw-r--r--app/assets/javascripts/lib/utils/notify.js8
-rw-r--r--app/assets/javascripts/lib/utils/number_utils.js33
-rw-r--r--app/assets/javascripts/lib/utils/text_utility.js23
-rw-r--r--app/assets/javascripts/lib/utils/tick_formats.js39
7 files changed, 122 insertions, 62 deletions
diff --git a/app/assets/javascripts/lib/graphql.js b/app/assets/javascripts/lib/graphql.js
index c05db4a5c71..2c5278d16ae 100644
--- a/app/assets/javascripts/lib/graphql.js
+++ b/app/assets/javascripts/lib/graphql.js
@@ -26,7 +26,11 @@ export default (resolvers = {}, config = {}) => {
createUploadLink(httpOptions),
new BatchHttpLink(httpOptions),
),
- cache: new InMemoryCache(config.cacheConfig),
+ cache: new InMemoryCache({
+ ...config.cacheConfig,
+ freezeResults: config.assumeImmutableResults,
+ }),
resolvers,
+ assumeImmutableResults: config.assumeImmutableResults,
});
};
diff --git a/app/assets/javascripts/lib/utils/chart_utils.js b/app/assets/javascripts/lib/utils/chart_utils.js
index 0f78756aac8..4a1e6c5d68c 100644
--- a/app/assets/javascripts/lib/utils/chart_utils.js
+++ b/app/assets/javascripts/lib/utils/chart_utils.js
@@ -81,3 +81,20 @@ export const lineChartOptions = ({ width, numberOfPoints, shouldAdjustFontSize }
},
},
});
+
+/**
+ * Takes a dataset and returns an array containing the y-values of it's first and last entry.
+ * (e.g., [['xValue1', 'yValue1'], ['xValue2', 'yValue2'], ['xValue3', 'yValue3']] will yield ['yValue1', 'yValue3'])
+ *
+ * @param {Array} data
+ * @returns {[*, *]}
+ */
+export const firstAndLastY = data => {
+ const [firstEntry] = data;
+ const [lastEntry] = data.slice(-1);
+
+ const firstY = firstEntry[1];
+ const lastY = lastEntry[1];
+
+ return [firstY, lastY];
+};
diff --git a/app/assets/javascripts/lib/utils/datetime_utility.js b/app/assets/javascripts/lib/utils/datetime_utility.js
index 37b0215f6f9..28143859e4c 100644
--- a/app/assets/javascripts/lib/utils/datetime_utility.js
+++ b/app/assets/javascripts/lib/utils/datetime_utility.js
@@ -78,11 +78,11 @@ export const getDayName = date =>
* @param {date} datetime
* @returns {String}
*/
-export const formatDate = datetime => {
+export const formatDate = (datetime, format = 'mmm d, yyyy h:MMtt Z') => {
if (_.isString(datetime) && datetime.match(/\d+-\d+\d+ /)) {
throw new Error(__('Invalid date'));
}
- return dateFormat(datetime, 'mmm d, yyyy h:MMtt Z');
+ return dateFormat(datetime, format);
};
/**
@@ -541,7 +541,7 @@ export const stringifyTime = (timeObject, fullNameFormat = false) => {
* The result cannot become negative.
*
* @param endDate date string that the time difference is calculated for
- * @return {number} number of milliseconds remaining until the given date
+ * @return {Number} number of milliseconds remaining until the given date
*/
export const calculateRemainingMilliseconds = endDate => {
const remainingMilliseconds = new Date(endDate).getTime() - Date.now();
@@ -552,15 +552,53 @@ export const calculateRemainingMilliseconds = endDate => {
* Subtracts a given number of days from a given date and returns the new date.
*
* @param {Date} date the date that we will substract days from
- * @param {number} daysInPast number of days that are subtracted from a given date
- * @returns {String} Date string in ISO format
+ * @param {Number} daysInPast number of days that are subtracted from a given date
+ * @returns {Date} Date in past as Date object
*/
-export const getDateInPast = (date, daysInPast) => {
- const dateClone = newDate(date);
- return new Date(
- dateClone.setTime(dateClone.getTime() - daysInPast * 24 * 60 * 60 * 1000),
- ).toISOString();
+export const getDateInPast = (date, daysInPast) =>
+ new Date(newDate(date).setDate(date.getDate() - daysInPast));
+
+/*
+ * Appending T00:00:00 makes JS assume local time and prevents it from shifting the date
+ * to match the user's time zone. We want to display the date in server time for now, to
+ * be consistent with the "edit issue -> due date" UI.
+ */
+
+export const newDateAsLocaleTime = date => {
+ const suffix = 'T00:00:00';
+ return new Date(`${date}${suffix}`);
};
export const beginOfDayTime = 'T00:00:00Z';
export const endOfDayTime = 'T23:59:59Z';
+
+/**
+ * @param {Date} d1
+ * @param {Date} d2
+ * @param {Function} formatter
+ * @return {Any[]} an array of formatted dates between 2 given dates (including start&end date)
+ */
+export const getDatesInRange = (d1, d2, formatter = x => x) => {
+ if (!(d1 instanceof Date) || !(d2 instanceof Date)) {
+ return [];
+ }
+ let startDate = d1.getTime();
+ const endDate = d2.getTime();
+ const oneDay = 24 * 3600 * 1000;
+ const range = [d1];
+
+ while (startDate < endDate) {
+ startDate += oneDay;
+ range.push(new Date(startDate));
+ }
+
+ return range.map(formatter);
+};
+
+/**
+ * Converts the supplied number of seconds to milliseconds.
+ *
+ * @param {Number} seconds
+ * @return {Number} number of milliseconds
+ */
+export const secondsToMilliseconds = seconds => seconds * 1000;
diff --git a/app/assets/javascripts/lib/utils/notify.js b/app/assets/javascripts/lib/utils/notify.js
index cd509a13193..8db08099b3f 100644
--- a/app/assets/javascripts/lib/utils/notify.js
+++ b/app/assets/javascripts/lib/utils/notify.js
@@ -1,8 +1,7 @@
-/* eslint-disable no-var, consistent-return, no-return-assign */
+/* eslint-disable consistent-return, no-return-assign */
function notificationGranted(message, opts, onclick) {
- var notification;
- notification = new Notification(message, opts);
+ const notification = new Notification(message, opts);
setTimeout(
() =>
// Hide the notification after X amount of seconds
@@ -21,8 +20,7 @@ function notifyPermissions() {
}
function notifyMe(message, body, icon, onclick) {
- var opts;
- opts = {
+ const opts = {
body,
icon,
};
diff --git a/app/assets/javascripts/lib/utils/number_utils.js b/app/assets/javascripts/lib/utils/number_utils.js
index 0f2cc57b1f9..bc87232f40b 100644
--- a/app/assets/javascripts/lib/utils/number_utils.js
+++ b/app/assets/javascripts/lib/utils/number_utils.js
@@ -117,3 +117,36 @@ export const median = arr => {
const sorted = arr.sort((a, b) => a - b);
return arr.length % 2 !== 0 ? sorted[middle] : (sorted[middle - 1] + sorted[middle]) / 2;
};
+
+/**
+ * Computes the change from one value to the other as a percentage.
+ * @param {Number} firstY
+ * @param {Number} lastY
+ * @returns {Number}
+ */
+export const changeInPercent = (firstY, lastY) => {
+ if (firstY === lastY) {
+ return 0;
+ }
+
+ return Math.round(((lastY - firstY) / Math.abs(firstY)) * 100);
+};
+
+/**
+ * Computes and formats the change from one value to the other as a percentage.
+ * Prepends the computed percentage with either "+" or "-" to indicate an in- or decrease and
+ * returns a given string if the result is not finite (for example, if the first value is "0").
+ * @param firstY
+ * @param lastY
+ * @param nonFiniteResult
+ * @returns {String}
+ */
+export const formattedChangeInPercent = (firstY, lastY, { nonFiniteResult = '-' } = {}) => {
+ const change = changeInPercent(firstY, lastY);
+
+ if (!Number.isFinite(change)) {
+ return nonFiniteResult;
+ }
+
+ return `${change >= 0 ? '+' : ''}${change}%`;
+};
diff --git a/app/assets/javascripts/lib/utils/text_utility.js b/app/assets/javascripts/lib/utils/text_utility.js
index d13fbeb5fc7..0c194d67bce 100644
--- a/app/assets/javascripts/lib/utils/text_utility.js
+++ b/app/assets/javascripts/lib/utils/text_utility.js
@@ -36,25 +36,26 @@ export const humanize = string =>
export const dasherize = str => str.replace(/[_\s]+/g, '-');
/**
- * Replaces whitespaces with hyphens, convert to lower case and remove non-allowed special characters
- * @param {String} str
+ * Replaces whitespace and non-sluggish characters with a given separator
+ * @param {String} str - The string to slugify
+ * @param {String=} separator - The separator used to separate words (defaults to "-")
* @returns {String}
*/
-export const slugify = str => {
+export const slugify = (str, separator = '-') => {
const slug = str
.trim()
.toLowerCase()
- .replace(/[^a-zA-Z0-9_.-]+/g, '-');
+ .replace(/[^a-zA-Z0-9_.-]+/g, separator);
- return slug === '-' ? '' : slug;
+ return slug === separator ? '' : slug;
};
/**
- * Replaces whitespaces with underscore and converts to lower case
+ * Replaces whitespace and non-sluggish characters with underscores
* @param {String} str
* @returns {String}
*/
-export const slugifyWithUnderscore = str => str.toLowerCase().replace(/\s+/g, '_');
+export const slugifyWithUnderscore = str => slugify(str, '_');
/**
* Truncates given text
@@ -139,6 +140,14 @@ export const stripHtml = (string, replace = '') => {
export const convertToCamelCase = string => string.replace(/(_\w)/g, s => s[1].toUpperCase());
/**
+ * Converts camelCase string to snake_case
+ *
+ * @param {*} string
+ */
+export const convertToSnakeCase = string =>
+ slugifyWithUnderscore(string.match(/([a-zA-Z][^A-Z]*)/g).join(' '));
+
+/**
* Converts a sentence to lower case from the second word onwards
* e.g. Hello World => Hello world
*
diff --git a/app/assets/javascripts/lib/utils/tick_formats.js b/app/assets/javascripts/lib/utils/tick_formats.js
deleted file mode 100644
index af3ca714400..00000000000
--- a/app/assets/javascripts/lib/utils/tick_formats.js
+++ /dev/null
@@ -1,39 +0,0 @@
-import { createDateTimeFormat } from '../../locale';
-
-let dateTimeFormats;
-
-export const initDateFormats = () => {
- const dayFormat = createDateTimeFormat({ month: 'short', day: 'numeric' });
- const monthFormat = createDateTimeFormat({ month: 'long' });
- const yearFormat = createDateTimeFormat({ year: 'numeric' });
-
- dateTimeFormats = {
- dayFormat,
- monthFormat,
- yearFormat,
- };
-};
-
-initDateFormats();
-
-/**
- Formats a localized date in way that it can be used for d3.js axis.tickFormat().
-
- That is, it displays
- - 4-digit for first of January
- - full month name for first of every month
- - day and abbreviated month otherwise
-
- see also https://github.com/d3/d3-3.x-api-reference/blob/master/SVG-Axes.md#tickFormat
- */
-export const dateTickFormat = date => {
- if (date.getDate() !== 1) {
- return dateTimeFormats.dayFormat.format(date);
- }
-
- if (date.getMonth() > 0) {
- return dateTimeFormats.monthFormat.format(date);
- }
-
- return dateTimeFormats.yearFormat.format(date);
-};