diff options
author | Tim Zallmann <tzallmann@gitlab.com> | 2017-08-06 05:57:49 +0000 |
---|---|---|
committer | Tim Zallmann <tzallmann@gitlab.com> | 2017-08-06 05:57:49 +0000 |
commit | 9b93508028e9e0a8ed0f4cbc9f20de568e31cac9 (patch) | |
tree | d28754eddf76e7928135acb281565acb20c26299 | |
parent | d1f27076131ef33e18d8d690da7ecf85ff60aa3c (diff) | |
parent | 013fe7643a531d2d705c364940155983a17d95c8 (diff) | |
download | gitlab-ce-9b93508028e9e0a8ed0f4cbc9f20de568e31cac9.tar.gz |
Merge branch '27616-fix-contributions-graph-utc-offset-mysql' into 'master'
Fix Timezone Inconsistencies in User Contribution Calendar
Closes #27616 and #1943
See merge request !13208
-rw-r--r-- | app/assets/javascripts/users/activity_calendar.js | 12 | ||||
-rw-r--r-- | app/assets/javascripts/users/user_tabs.js | 8 | ||||
-rw-r--r-- | app/assets/stylesheets/framework/calendar.scss | 1 | ||||
-rw-r--r-- | app/views/users/calendar_activities.html.haml | 6 | ||||
-rw-r--r-- | app/views/users/show.html.haml | 2 | ||||
-rw-r--r-- | changelogs/unreleased/27616-fix-contributions-graph-utc-offset-mysql.yml | 4 | ||||
-rw-r--r-- | lib/gitlab/contributions_calendar.rb | 14 | ||||
-rw-r--r-- | spec/lib/gitlab/contributions_calendar_spec.rb | 38 |
8 files changed, 70 insertions, 15 deletions
diff --git a/app/assets/javascripts/users/activity_calendar.js b/app/assets/javascripts/users/activity_calendar.js index 3dac31c2121..5e947769f8a 100644 --- a/app/assets/javascripts/users/activity_calendar.js +++ b/app/assets/javascripts/users/activity_calendar.js @@ -7,6 +7,14 @@ const LOADING_HTML = ` </div> `; +function getSystemDate(systemUtcOffsetSeconds) { + const date = new Date(); + const localUtcOffsetMinutes = 0 - date.getTimezoneOffset(); + const systemUtcOffsetMinutes = systemUtcOffsetSeconds / 60; + date.setMinutes((date.getMinutes() - localUtcOffsetMinutes) + systemUtcOffsetMinutes); + return date; +} + function formatTooltipText({ date, count }) { const dateObject = new Date(date); const dateDayName = gl.utils.getDayName(dateObject); @@ -22,7 +30,7 @@ function formatTooltipText({ date, count }) { const initColorKey = () => d3.scale.linear().range(['#acd5f2', '#254e77']).domain([0, 3]); export default class ActivityCalendar { - constructor(container, timestamps, calendarActivitiesPath) { + constructor(container, timestamps, calendarActivitiesPath, utcOffset = 0) { this.calendarActivitiesPath = calendarActivitiesPath; this.clickDay = this.clickDay.bind(this); this.currentSelectedDate = ''; @@ -37,7 +45,7 @@ export default class ActivityCalendar { this.timestampsTmp = []; let group = 0; - const today = new Date(); + const today = getSystemDate(utcOffset); today.setHours(0, 0, 0, 0, 0); const oneYearAgo = new Date(today); diff --git a/app/assets/javascripts/users/user_tabs.js b/app/assets/javascripts/users/user_tabs.js index 5fe6603ce7b..1215b265e28 100644 --- a/app/assets/javascripts/users/user_tabs.js +++ b/app/assets/javascripts/users/user_tabs.js @@ -150,15 +150,21 @@ export default class UserTabs { const $calendarWrap = this.$parentEl.find('.user-calendar'); const calendarPath = $calendarWrap.data('calendarPath'); const calendarActivitiesPath = $calendarWrap.data('calendarActivitiesPath'); + const utcOffset = $calendarWrap.data('utcOffset'); + let utcFormatted = 'UTC'; + if (utcOffset !== 0) { + utcFormatted = `UTC${utcOffset > 0 ? '+' : ''}${(utcOffset / 3600)}`; + } $.ajax({ dataType: 'json', url: calendarPath, success: (activityData) => { $calendarWrap.html(CALENDAR_TEMPLATE); + $calendarWrap.find('.calendar-hint').append(`(Timezone: ${utcFormatted})`); // eslint-disable-next-line no-new - new ActivityCalendar('.js-contrib-calendar', activityData, calendarActivitiesPath); + new ActivityCalendar('.js-contrib-calendar', activityData, calendarActivitiesPath, utcOffset); }, }); diff --git a/app/assets/stylesheets/framework/calendar.scss b/app/assets/stylesheets/framework/calendar.scss index 0ac095f7d8f..0ded4a3b423 100644 --- a/app/assets/stylesheets/framework/calendar.scss +++ b/app/assets/stylesheets/framework/calendar.scss @@ -45,6 +45,7 @@ margin-top: -23px; float: right; font-size: 12px; + direction: ltr; } .pika-single.gitlab-theme { diff --git a/app/views/users/calendar_activities.html.haml b/app/views/users/calendar_activities.html.haml index 805a346a85e..6b1d75c6e72 100644 --- a/app/views/users/calendar_activities.html.haml +++ b/app/views/users/calendar_activities.html.haml @@ -1,6 +1,6 @@ %h4.prepend-top-20 Contributions for - %strong= @calendar_date.to_s(:short) + %strong= @calendar_date.to_s(:medium) - if @events.any? %ul.bordered-list @@ -8,7 +8,7 @@ %li %span.light %i.fa.fa-clock-o - = event.created_at.to_s(:time) + = event.created_at.strftime('%-I:%M%P') - if event.push? #{event.action_name} #{event.ref_type} %strong @@ -30,4 +30,4 @@ = event.project_name - else %p - No contributions found for #{@calendar_date.to_s(:short)} + No contributions found for #{@calendar_date.to_s(:medium)} diff --git a/app/views/users/show.html.haml b/app/views/users/show.html.haml index a449706c567..879e0f99b14 100644 --- a/app/views/users/show.html.haml +++ b/app/views/users/show.html.haml @@ -104,7 +104,7 @@ .tab-content #activity.tab-pane .row-content-block.calender-block.white.second-block.hidden-xs - .user-calendar{ data: { calendar_path: user_calendar_path(@user, :json), calendar_activities_path: user_calendar_activities_path } } + .user-calendar{ data: { calendar_path: user_calendar_path(@user, :json), calendar_activities_path: user_calendar_activities_path, utc_offset: Time.zone.utc_offset } } %h4.center.light %i.fa.fa-spinner.fa-spin .user-calendar-activities diff --git a/changelogs/unreleased/27616-fix-contributions-graph-utc-offset-mysql.yml b/changelogs/unreleased/27616-fix-contributions-graph-utc-offset-mysql.yml new file mode 100644 index 00000000000..1b3c3b8538d --- /dev/null +++ b/changelogs/unreleased/27616-fix-contributions-graph-utc-offset-mysql.yml @@ -0,0 +1,4 @@ +--- +title: Fix timezone inconsistencies in user contribution graph +merge_request: 13208 +author: diff --git a/lib/gitlab/contributions_calendar.rb b/lib/gitlab/contributions_calendar.rb index bf557103cfd..0735243e021 100644 --- a/lib/gitlab/contributions_calendar.rb +++ b/lib/gitlab/contributions_calendar.rb @@ -48,7 +48,7 @@ module Gitlab end def starting_month - Date.today.month + Date.current.month end private @@ -66,12 +66,18 @@ module Gitlab .select(:id) conditions = t[:created_at].gteq(date_from.beginning_of_day) - .and(t[:created_at].lteq(Date.today.end_of_day)) + .and(t[:created_at].lteq(Date.current.end_of_day)) .and(t[:author_id].eq(contributor.id)) + date_interval = if Gitlab::Database.postgresql? + "INTERVAL '#{Time.zone.now.utc_offset} seconds'" + else + "INTERVAL #{Time.zone.now.utc_offset} SECOND" + end + Event.reorder(nil) - .select(t[:project_id], t[:target_type], t[:action], 'date(created_at) AS date', 'count(id) as total_amount') - .group(t[:project_id], t[:target_type], t[:action], 'date(created_at)') + .select(t[:project_id], t[:target_type], t[:action], "date(created_at + #{date_interval}) AS date", 'count(id) as total_amount') + .group(t[:project_id], t[:target_type], t[:action], "date(created_at + #{date_interval})") .where(conditions) .having(t[:project_id].in(Arel::Nodes::SqlLiteral.new(authed_projects.to_sql))) end diff --git a/spec/lib/gitlab/contributions_calendar_spec.rb b/spec/lib/gitlab/contributions_calendar_spec.rb index 9217d48087e..f1655854486 100644 --- a/spec/lib/gitlab/contributions_calendar_spec.rb +++ b/spec/lib/gitlab/contributions_calendar_spec.rb @@ -22,12 +22,14 @@ describe Gitlab::ContributionsCalendar do end end - let(:today) { Time.now.to_date } + let(:today) { Time.now.utc.to_date } + let(:yesterday) { today - 1.day } + let(:tomorrow) { today + 1.day } let(:last_week) { today - 7.days } let(:last_year) { today - 1.year } before do - travel_to today + travel_to Time.now.utc.end_of_day end after do @@ -38,7 +40,7 @@ describe Gitlab::ContributionsCalendar do described_class.new(contributor, current_user) end - def create_event(project, day) + def create_event(project, day, hour = 0) @targets ||= {} @targets[project] ||= create(:issue, project: project, author: contributor) @@ -47,7 +49,7 @@ describe Gitlab::ContributionsCalendar do action: Event::CREATED, target: @targets[project], author: contributor, - created_at: day + created_at: DateTime.new(day.year, day.month, day.day, hour) ) end @@ -68,6 +70,34 @@ describe Gitlab::ContributionsCalendar do expect(calendar(user).activity_dates[today]).to eq(0) expect(calendar(contributor).activity_dates[today]).to eq(2) end + + context "when events fall under different dates depending on the time zone" do + before do + create_event(public_project, today, 1) + create_event(public_project, today, 4) + create_event(public_project, today, 10) + create_event(public_project, today, 16) + create_event(public_project, today, 23) + end + + it "renders correct event counts within the UTC timezone" do + Time.use_zone('UTC') do + expect(calendar.activity_dates).to eq(today => 5) + end + end + + it "renders correct event counts within the Sydney timezone" do + Time.use_zone('Sydney') do + expect(calendar.activity_dates).to eq(today => 3, tomorrow => 2) + end + end + + it "renders correct event counts within the US Central timezone" do + Time.use_zone('Central Time (US & Canada)') do + expect(calendar.activity_dates).to eq(yesterday => 2, today => 3) + end + end + end end describe '#events_by_date' do |