From 9955dc29a863ad997efe2926875c29f963ba94d4 Mon Sep 17 00:00:00 2001
From: Annabel Dunstone <annabel.dunstone@gmail.com>
Date: Tue, 12 Jul 2016 17:52:36 -0500
Subject: [PATCH] Update timeago to shorter representation

---
 CHANGELOG                                     |  1 +
 app/assets/javascripts/application.js         |  6 ++-
 .../javascripts/lib/utils/datetime_utility.js | 38 ++++++++++++++++++-
 app/helpers/application_helper.rb             |  8 +++-
 .../projects/ci/pipelines/_pipeline.html.haml |  2 +-
 spec/helpers/application_helper_spec.rb       | 17 ++++++++-
 6 files changed, 64 insertions(+), 8 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG
index 77bcea54cf9a5..9e5d00c01f86a 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -19,6 +19,7 @@ v 8.11.0 (unreleased)
   - Add "No one can push" as an option for protected branches. !5081
   - Improve performance of AutolinkFilter#text_parse by using XPath
   - Environments have an url to link to
+  - Update `timeago` plugin to use multiple string/locale settings
   - Remove unused images (ClemMakesApps)
   - Limit git rev-list output count to one in forced push check
   - Clean up unused routes (Josef Strzibny)
diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js
index 127e568adc975..f1aab067351da 100644
--- a/app/assets/javascripts/application.js
+++ b/app/assets/javascripts/application.js
@@ -287,7 +287,7 @@
       $('.page-with-sidebar').toggleClass('page-sidebar-collapsed page-sidebar-expanded').removeClass('page-sidebar-pinned');
       $('.navbar-fixed-top').removeClass('header-pinned-nav');
     }
-    return $document.off('click', '.js-nav-pin').on('click', '.js-nav-pin', function(e) {
+    $document.off('click', '.js-nav-pin').on('click', '.js-nav-pin', function(e) {
       var $page, $pinBtn, $tooltip, $topNav, doPinNav, tooltipText;
       e.preventDefault();
       $pinBtn = $(e.currentTarget);
@@ -315,6 +315,8 @@
       $tooltip.find('.tooltip-inner').text(tooltipText);
       return $pinBtn.attr('title', tooltipText).tooltip('fixTitle');
     });
-  });
 
+    // Custom time ago
+    gl.utils.shortTimeAgo($('.js-short-timeago'));
+  });
 }).call(this);
diff --git a/app/assets/javascripts/lib/utils/datetime_utility.js b/app/assets/javascripts/lib/utils/datetime_utility.js
index e817261f2103a..10afa7e432985 100644
--- a/app/assets/javascripts/lib/utils/datetime_utility.js
+++ b/app/assets/javascripts/lib/utils/datetime_utility.js
@@ -8,13 +8,16 @@
       base.utils = {};
     }
     w.gl.utils.days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
+
     w.gl.utils.formatDate = function(datetime) {
       return dateFormat(datetime, 'mmm d, yyyy h:MMtt Z');
     };
+
     w.gl.utils.getDayName = function(date) {
       return this.days[date.getDay()];
     };
-    return w.gl.utils.localTimeAgo = function($timeagoEls, setTimeago) {
+
+    w.gl.utils.localTimeAgo = function($timeagoEls, setTimeago) {
       if (setTimeago == null) {
         setTimeago = true;
       }
@@ -31,6 +34,39 @@
         });
       }
     };
+
+    w.gl.utils.shortTimeAgo = function($el) {
+      var shortLocale, tmpLocale;
+      shortLocale = {
+        prefixAgo: null,
+        prefixFromNow: null,
+        suffixAgo: 'ago',
+        suffixFromNow: 'from now',
+        seconds: '1 min',
+        minute: '1 min',
+        minutes: '%d mins',
+        hour: '1 hr',
+        hours: '%d hrs',
+        day: '1 day',
+        days: '%d days',
+        month: '1 month',
+        months: '%d months',
+        year: '1 year',
+        years: '%d years',
+        wordSeparator: ' ',
+        numbers: []
+      };
+      tmpLocale = $.timeago.settings.strings;
+      $el.each(function(el) {
+        var $el1;
+        $el1 = $(this);
+        return $el1.attr('title', gl.utils.formatDate($el.attr('datetime')));
+      });
+      $.timeago.settings.strings = shortLocale;
+      $el.timeago();
+      $.timeago.settings.strings = tmpLocale;
+    };
+
   })(window);
 
 }).call(this);
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 50de93d4bdf9f..c3613bc67dd00 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -163,9 +163,13 @@ def extra_config
   # `html_class` argument is provided.
   #
   # Returns an HTML-safe String
-  def time_ago_with_tooltip(time, placement: 'top', html_class: 'time_ago', skip_js: false)
+  def time_ago_with_tooltip(time, placement: 'top', html_class: '', skip_js: false, short_format: false)
+    css_classes = short_format ? 'js-short-timeago' : 'js-timeago'
+    css_classes << " #{html_class}" unless html_class.blank?
+    css_classes << ' js-timeago-pending' unless skip_js
+
     element = content_tag :time, time.to_s,
-      class: "#{html_class} js-timeago #{"js-timeago-pending" unless skip_js}",
+      class: css_classes,
       datetime: time.to_time.getutc.iso8601,
       title: time.to_time.in_time_zone.to_s(:medium),
       data: { toggle: 'tooltip', placement: placement, container: 'body' }
diff --git a/app/views/projects/ci/pipelines/_pipeline.html.haml b/app/views/projects/ci/pipelines/_pipeline.html.haml
index 558c35553da5c..9a594877803ab 100644
--- a/app/views/projects/ci/pipelines/_pipeline.html.haml
+++ b/app/views/projects/ci/pipelines/_pipeline.html.haml
@@ -53,7 +53,7 @@
     - if pipeline.finished_at
       %p.finished-at
         = icon("calendar")
-        #{time_ago_with_tooltip(pipeline.finished_at)}
+        #{time_ago_with_tooltip(pipeline.finished_at, short_format: true, skip_js: true)}
 
   %td.pipeline-actions
     .controls.hidden-xs.pull-right
diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb
index bb28866f01009..3e15a137e33a6 100644
--- a/spec/helpers/application_helper_spec.rb
+++ b/spec/helpers/application_helper_spec.rb
@@ -218,12 +218,12 @@ def element(*arguments)
     end
 
     it 'includes a default js-timeago class' do
-      expect(element.attr('class')).to eq 'time_ago js-timeago js-timeago-pending'
+      expect(element.attr('class')).to eq 'js-timeago js-timeago-pending'
     end
 
     it 'accepts a custom html_class' do
       expect(element(html_class: 'custom_class').attr('class')).
-        to eq 'custom_class js-timeago js-timeago-pending'
+        to eq 'js-timeago custom_class js-timeago-pending'
     end
 
     it 'accepts a custom tooltip placement' do
@@ -244,6 +244,19 @@ def element(*arguments)
     it 'converts to Time' do
       expect { helper.time_ago_with_tooltip(Date.today) }.not_to raise_error
     end
+
+    it 'add class for the short format and includes inline script' do
+      timeago_element = element(short_format: 'short')
+      expect(timeago_element.attr('class')).to eq 'js-short-timeago js-timeago-pending'
+      script_element = timeago_element.next_element
+      expect(script_element.name).to eq 'script'
+    end
+
+    it 'add class for the short format and does not include inline script' do
+      timeago_element = element(short_format: 'short', skip_js: true)
+      expect(timeago_element.attr('class')).to eq 'js-short-timeago'
+      expect(timeago_element.next_element).to eq nil
+    end
   end
 
   describe 'render_markup' do
-- 
GitLab