Commit 694b8d68 authored by Tim Zallmann's avatar Tim Zallmann

Merge branch '34958-update-timeago-to-the-latest-release' into 'master'

Resolve "Update timeago to the latest release"

Closes #34958

See merge request gitlab-org/gitlab!19407
parents 83681a9e aa26b9f0
<script>
/* eslint-disable @gitlab/vue-i18n/no-bare-strings */
import { __, sprintf } from '~/locale';
import Timeago from 'timeago.js';
import { format } from 'timeago.js';
import _ from 'underscore';
import { GlTooltipDirective } from '@gitlab/ui';
import UserAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue';
......@@ -23,7 +23,6 @@ import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
*
* Renders a table row for each environment.
*/
const timeagoInstance = new Timeago();
export default {
components: {
......@@ -123,7 +122,7 @@ export default {
*/
deployedDate() {
if (this.canShowDate) {
return timeagoInstance.format(this.model.last_deployment.deployed_at);
return format(this.model.last_deployment.deployed_at);
}
return '';
},
......
import $ from 'jquery';
import _ from 'underscore';
import timeago from 'timeago.js';
import * as timeago from 'timeago.js';
import dateFormat from 'dateformat';
import { languageCode, s__, __, n__ } from '../../locale';
......@@ -92,90 +92,80 @@ export const formatDate = (datetime, format = 'mmm d, yyyy h:MMtt Z') => {
*/
const timeagoLanguageCode = languageCode().replace(/-/g, '_');
let timeagoInstance;
/**
* Sets a timeago Instance
* Registers timeago locales
*/
export const getTimeago = () => {
if (!timeagoInstance) {
const memoizedLocaleRemaining = () => {
const cache = [];
const timeAgoLocaleRemaining = [
() => [s__('Timeago|just now'), s__('Timeago|right now')],
() => [s__('Timeago|just now'), s__('Timeago|%s seconds remaining')],
() => [s__('Timeago|1 minute ago'), s__('Timeago|1 minute remaining')],
() => [s__('Timeago|%s minutes ago'), s__('Timeago|%s minutes remaining')],
() => [s__('Timeago|1 hour ago'), s__('Timeago|1 hour remaining')],
() => [s__('Timeago|%s hours ago'), s__('Timeago|%s hours remaining')],
() => [s__('Timeago|1 day ago'), s__('Timeago|1 day remaining')],
() => [s__('Timeago|%s days ago'), s__('Timeago|%s days remaining')],
() => [s__('Timeago|1 week ago'), s__('Timeago|1 week remaining')],
() => [s__('Timeago|%s weeks ago'), s__('Timeago|%s weeks remaining')],
() => [s__('Timeago|1 month ago'), s__('Timeago|1 month remaining')],
() => [s__('Timeago|%s months ago'), s__('Timeago|%s months remaining')],
() => [s__('Timeago|1 year ago'), s__('Timeago|1 year remaining')],
() => [s__('Timeago|%s years ago'), s__('Timeago|%s years remaining')],
];
return (number, index) => {
if (cache[index]) {
return cache[index];
}
cache[index] = timeAgoLocaleRemaining[index] && timeAgoLocaleRemaining[index]();
return cache[index];
};
};
const memoizedLocale = () => {
const cache = [];
const timeAgoLocale = [
() => [s__('Timeago|just now'), s__('Timeago|right now')],
() => [s__('Timeago|just now'), s__('Timeago|in %s seconds')],
() => [s__('Timeago|1 minute ago'), s__('Timeago|in 1 minute')],
() => [s__('Timeago|%s minutes ago'), s__('Timeago|in %s minutes')],
() => [s__('Timeago|1 hour ago'), s__('Timeago|in 1 hour')],
() => [s__('Timeago|%s hours ago'), s__('Timeago|in %s hours')],
() => [s__('Timeago|1 day ago'), s__('Timeago|in 1 day')],
() => [s__('Timeago|%s days ago'), s__('Timeago|in %s days')],
() => [s__('Timeago|1 week ago'), s__('Timeago|in 1 week')],
() => [s__('Timeago|%s weeks ago'), s__('Timeago|in %s weeks')],
() => [s__('Timeago|1 month ago'), s__('Timeago|in 1 month')],
() => [s__('Timeago|%s months ago'), s__('Timeago|in %s months')],
() => [s__('Timeago|1 year ago'), s__('Timeago|in 1 year')],
() => [s__('Timeago|%s years ago'), s__('Timeago|in %s years')],
];
return (number, index) => {
if (cache[index]) {
return cache[index];
}
cache[index] = timeAgoLocale[index] && timeAgoLocale[index]();
return cache[index];
};
};
timeago.register(timeagoLanguageCode, memoizedLocale());
timeago.register(`${timeagoLanguageCode}-remaining`, memoizedLocaleRemaining());
timeagoInstance = timeago();
}
const memoizedLocaleRemaining = () => {
const cache = [];
const timeAgoLocaleRemaining = [
() => [s__('Timeago|just now'), s__('Timeago|right now')],
() => [s__('Timeago|just now'), s__('Timeago|%s seconds remaining')],
() => [s__('Timeago|1 minute ago'), s__('Timeago|1 minute remaining')],
() => [s__('Timeago|%s minutes ago'), s__('Timeago|%s minutes remaining')],
() => [s__('Timeago|1 hour ago'), s__('Timeago|1 hour remaining')],
() => [s__('Timeago|%s hours ago'), s__('Timeago|%s hours remaining')],
() => [s__('Timeago|1 day ago'), s__('Timeago|1 day remaining')],
() => [s__('Timeago|%s days ago'), s__('Timeago|%s days remaining')],
() => [s__('Timeago|1 week ago'), s__('Timeago|1 week remaining')],
() => [s__('Timeago|%s weeks ago'), s__('Timeago|%s weeks remaining')],
() => [s__('Timeago|1 month ago'), s__('Timeago|1 month remaining')],
() => [s__('Timeago|%s months ago'), s__('Timeago|%s months remaining')],
() => [s__('Timeago|1 year ago'), s__('Timeago|1 year remaining')],
() => [s__('Timeago|%s years ago'), s__('Timeago|%s years remaining')],
];
return (number, index) => {
if (cache[index]) {
return cache[index];
}
cache[index] = timeAgoLocaleRemaining[index] && timeAgoLocaleRemaining[index]();
return cache[index];
};
};
return timeagoInstance;
const memoizedLocale = () => {
const cache = [];
const timeAgoLocale = [
() => [s__('Timeago|just now'), s__('Timeago|right now')],
() => [s__('Timeago|just now'), s__('Timeago|in %s seconds')],
() => [s__('Timeago|1 minute ago'), s__('Timeago|in 1 minute')],
() => [s__('Timeago|%s minutes ago'), s__('Timeago|in %s minutes')],
() => [s__('Timeago|1 hour ago'), s__('Timeago|in 1 hour')],
() => [s__('Timeago|%s hours ago'), s__('Timeago|in %s hours')],
() => [s__('Timeago|1 day ago'), s__('Timeago|in 1 day')],
() => [s__('Timeago|%s days ago'), s__('Timeago|in %s days')],
() => [s__('Timeago|1 week ago'), s__('Timeago|in 1 week')],
() => [s__('Timeago|%s weeks ago'), s__('Timeago|in %s weeks')],
() => [s__('Timeago|1 month ago'), s__('Timeago|in 1 month')],
() => [s__('Timeago|%s months ago'), s__('Timeago|in %s months')],
() => [s__('Timeago|1 year ago'), s__('Timeago|in 1 year')],
() => [s__('Timeago|%s years ago'), s__('Timeago|in %s years')],
];
return (number, index) => {
if (cache[index]) {
return cache[index];
}
cache[index] = timeAgoLocale[index] && timeAgoLocale[index]();
return cache[index];
};
};
timeago.register(timeagoLanguageCode, memoizedLocale());
timeago.register(`${timeagoLanguageCode}-remaining`, memoizedLocaleRemaining());
export const getTimeago = () => timeago;
/**
* For the given elements, sets a tooltip with a formatted date.
* @param {JQuery} $timeagoEls
* @param {Boolean} setTimeago
*/
export const localTimeAgo = ($timeagoEls, setTimeago = true) => {
getTimeago();
$timeagoEls.each((i, el) => {
$(el).text(timeagoInstance.format($(el).attr('datetime'), timeagoLanguageCode));
$(el).text(timeago.format($(el).attr('datetime'), timeagoLanguageCode));
});
if (!setTimeago) {
......@@ -207,9 +197,7 @@ export const timeFor = (time, expiredLabel) => {
if (new Date(time) < new Date()) {
return expiredLabel || s__('Timeago|Past due');
}
return getTimeago()
.format(time, `${timeagoLanguageCode}-remaining`)
.trim();
return timeago.format(time, `${timeagoLanguageCode}-remaining`).trim();
};
export const getDayDifference = (a, b) => {
......
import Timeago from 'timeago.js';
import { format } from 'timeago.js';
import _ from 'underscore';
import getStateKey from 'ee_else_ce/vue_merge_request_widget/stores/get_state_key';
import { stateKey } from './state_maps';
......@@ -213,9 +213,7 @@ export default class MergeRequestStore {
return '';
}
const timeagoInstance = new Timeago();
return timeagoInstance.format(date);
return format(date);
}
static getPreferredAutoMergeStrategy(availableAutoMergeStrategies) {
......
---
title: Update timeago to the latest release
merge_request: 19407
author:
type: other
import { __, s__ } from '~/locale';
import * as datetimeUtility from '~/lib/utils/datetime_utility';
describe('Date time utils', () => {
describe('timeFor', () => {
it('returns `past due` when in past', () => {
it('returns localize `past due` when in past', () => {
const date = new Date();
date.setFullYear(date.getFullYear() - 1);
expect(datetimeUtility.timeFor(date)).toBe('Past due');
expect(datetimeUtility.timeFor(date)).toBe(s__('Timeago|Past due'));
});
it('returns remaining time when in the future', () => {
it('returns localized remaining time when in the future', () => {
const date = new Date();
date.setFullYear(date.getFullYear() + 1);
......@@ -17,51 +18,51 @@ describe('Date time utils', () => {
// short of a full year, timeFor will return '11 months remaining'
date.setDate(date.getDate() + 1);
expect(datetimeUtility.timeFor(date)).toBe('1 year remaining');
expect(datetimeUtility.timeFor(date)).toBe(s__('Timeago|1 year remaining'));
});
});
describe('get day name', () => {
describe('get localized day name', () => {
it('should return Sunday', () => {
const day = datetimeUtility.getDayName(new Date('07/17/2016'));
expect(day).toBe('Sunday');
expect(day).toBe(__('Sunday'));
});
it('should return Monday', () => {
const day = datetimeUtility.getDayName(new Date('07/18/2016'));
expect(day).toBe('Monday');
expect(day).toBe(__('Monday'));
});
it('should return Tuesday', () => {
const day = datetimeUtility.getDayName(new Date('07/19/2016'));
expect(day).toBe('Tuesday');
expect(day).toBe(__('Tuesday'));
});
it('should return Wednesday', () => {
const day = datetimeUtility.getDayName(new Date('07/20/2016'));
expect(day).toBe('Wednesday');
expect(day).toBe(__('Wednesday'));
});
it('should return Thursday', () => {
const day = datetimeUtility.getDayName(new Date('07/21/2016'));
expect(day).toBe('Thursday');
expect(day).toBe(__('Thursday'));
});
it('should return Friday', () => {
const day = datetimeUtility.getDayName(new Date('07/22/2016'));
expect(day).toBe('Friday');
expect(day).toBe(__('Friday'));
});
it('should return Saturday', () => {
const day = datetimeUtility.getDayName(new Date('07/23/2016'));
expect(day).toBe('Saturday');
expect(day).toBe(__('Saturday'));
});
});
......@@ -114,10 +115,10 @@ describe('Date time utils', () => {
describe('timeIntervalInWords', () => {
it('should return string with number of minutes and seconds', () => {
expect(datetimeUtility.timeIntervalInWords(9.54)).toEqual('9 seconds');
expect(datetimeUtility.timeIntervalInWords(1)).toEqual('1 second');
expect(datetimeUtility.timeIntervalInWords(200)).toEqual('3 minutes 20 seconds');
expect(datetimeUtility.timeIntervalInWords(6008)).toEqual('100 minutes 8 seconds');
expect(datetimeUtility.timeIntervalInWords(9.54)).toEqual(s__('Timeago|9 seconds'));
expect(datetimeUtility.timeIntervalInWords(1)).toEqual(s__('Timeago|1 second'));
expect(datetimeUtility.timeIntervalInWords(200)).toEqual(s__('Timeago|3 minutes 20 seconds'));
expect(datetimeUtility.timeIntervalInWords(6008)).toEqual(s__('Timeago|100 minutes 8 seconds'));
});
});
......@@ -125,15 +126,15 @@ describe('dateInWords', () => {
const date = new Date('07/01/2016');
it('should return date in words', () => {
expect(datetimeUtility.dateInWords(date)).toEqual('July 1, 2016');
expect(datetimeUtility.dateInWords(date)).toEqual(s__('July 1, 2016'));
});
it('should return abbreviated month name', () => {
expect(datetimeUtility.dateInWords(date, true)).toEqual('Jul 1, 2016');
expect(datetimeUtility.dateInWords(date, true)).toEqual(s__('Jul 1, 2016'));
});
it('should return date in words without year', () => {
expect(datetimeUtility.dateInWords(date, true, true)).toEqual('Jul 1');
expect(datetimeUtility.dateInWords(date, true, true)).toEqual(s__('Jul 1'));
});
});
......@@ -141,11 +142,11 @@ describe('monthInWords', () => {
const date = new Date('2017-01-20');
it('returns month name from provided date', () => {
expect(datetimeUtility.monthInWords(date)).toBe('January');
expect(datetimeUtility.monthInWords(date)).toBe(s__('January'));
});
it('returns abbreviated month name from provided date', () => {
expect(datetimeUtility.monthInWords(date, true)).toBe('Jan');
expect(datetimeUtility.monthInWords(date, true)).toBe(s__('Jan'));
});
});
......
import 'timeago.js';
import { format } from 'timeago.js';
import Vue from 'vue';
import environmentItemComp from '~/environments/components/environment_item.vue';
......@@ -139,8 +139,7 @@ describe('Environment item', () => {
});
it('should render last deployment date', () => {
const timeagoInstance = new timeago(); // eslint-disable-line
const formatedDate = timeagoInstance.format(environment.last_deployment.deployed_at);
const formatedDate = format(environment.last_deployment.deployed_at);
expect(
component.$el.querySelector('.environment-created-date-timeago').textContent,
......
......@@ -1047,11 +1047,6 @@
"@types/istanbul-lib-coverage" "*"
"@types/istanbul-lib-report" "*"
"@types/jquery@^2.0.40":
version "2.0.48"
resolved "https://registry.yarnpkg.com/@types/jquery/-/jquery-2.0.48.tgz#3e90d8cde2d29015e5583017f7830cb3975b2eef"
integrity sha512-nNLzUrVjaRV/Ds1eHZLYTd7IZxs38cwwLSaqMJj8OTXY8xNUbxSK69bi9cMLvQ7dm/IBeQ1wHwQ0S1uYa0rd2w==
"@types/minimatch@*":
version "3.0.3"
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
......@@ -10877,12 +10872,10 @@ thunky@^0.1.0:
resolved "https://registry.yarnpkg.com/thunky/-/thunky-0.1.0.tgz#bf30146824e2b6e67b0f2d7a4ac8beb26908684e"
integrity sha1-vzAUaCTituZ7Dy16Ssi+smkIaE4=
timeago.js@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/timeago.js/-/timeago.js-3.0.2.tgz#32a67e7c0d887ea42ca588d3aae26f77de5e76cc"
integrity sha1-MqZ+fA2IfqQspYjTquJvd95edsw=
dependencies:
"@types/jquery" "^2.0.40"
timeago.js@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/timeago.js/-/timeago.js-4.0.1.tgz#4be4aa19565ceaeb0da31fe14e01ce6ca4742da6"
integrity sha512-ePzZuMoJqUc44hJbUYtY1qtzU7IammxooDCcFKogLkS5Nj+iCabR0ZlmNOFX8Dm1r5EpvR5q/PotOJli/mEPew==
timed-out@^4.0.0:
version "4.0.1"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment