summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHannes Rosenögger <123haynes@gmail.com>2015-03-13 11:39:26 +0100
committerHannes Rosenögger <123haynes@gmail.com>2015-03-18 08:42:42 +0100
commit9e5738b0072f8715d52801f3469be9f3742beb97 (patch)
treee6f83c4c42e05309ef20150796aefe372026e68f
parentdbd347bfa00e133da8ac178612ed8c30ef871ca4 (diff)
downloadgitlab-ce-9e5738b0072f8715d52801f3469be9f3742beb97.tar.gz
Extend the commit calendar to show the actual commits for a date
-rw-r--r--CHANGELOG1
-rw-r--r--app/assets/javascripts/calendar.js.coffee17
-rw-r--r--app/assets/stylesheets/generic/calendar.scss62
-rw-r--r--app/controllers/users_controller.rb19
-rw-r--r--app/models/project_contributions.rb9
-rw-r--r--app/models/repository.rb14
-rw-r--r--app/views/users/calendar.html.haml3
-rw-r--r--app/views/users/calendar_activities.html.haml33
-rw-r--r--app/views/users/show.html.haml1
-rw-r--r--config/routes.rb5
-rw-r--r--db/schema.rb2
-rw-r--r--lib/gitlab/commits_calendar.rb8
-rw-r--r--spec/controllers/users_controller_spec.rb48
-rw-r--r--spec/models/repository_spec.rb19
14 files changed, 202 insertions, 39 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 09b60e8e54a..b9b9ec964a1 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,7 @@
Please view this file on the master branch, on stable branches it's out of date.
v 7.10.0 (unreleased)
+ - extend the commit calendar to show the actual commits made on a date (Hannes Rosenögger)
- Add a service to support external wikis (Hannes Rosenögger)
v 7.9.0 (unreleased)
diff --git a/app/assets/javascripts/calendar.js.coffee b/app/assets/javascripts/calendar.js.coffee
index 19ea4ccc4cf..2891a48e249 100644
--- a/app/assets/javascripts/calendar.js.coffee
+++ b/app/assets/javascripts/calendar.js.coffee
@@ -4,7 +4,7 @@ class @calendar
day: "numeric"
year: "numeric"
- constructor: (timestamps, starting_year, starting_month) ->
+ constructor: (timestamps, starting_year, starting_month, calendar_activities_path) ->
cal = new CalHeatMap()
cal.init
itemName: ["commit"]
@@ -26,5 +26,16 @@ class @calendar
]
legendCellPadding: 3
onClick: (date, count) ->
- return
- return
+ formated_date = date.getFullYear() + "-" + (date.getMonth()+1) + "-" + date.getDate()
+ $(".calendar_commit_activity").fadeOut 400
+ $.ajax
+ url: calendar_activities_path
+ data:
+ date: formated_date
+ cache: false
+ dataType: "html"
+ success: (data) ->
+ $(".user-calendar-activities").html data
+ $(".calendar_commit_activity").find(".js-toggle-content").hide()
+ $(".calendar_commit_activity").fadeIn 400
+
diff --git a/app/assets/stylesheets/generic/calendar.scss b/app/assets/stylesheets/generic/calendar.scss
index 9483b26164e..e2ab7fc51a5 100644
--- a/app/assets/stylesheets/generic/calendar.scss
+++ b/app/assets/stylesheets/generic/calendar.scss
@@ -1,29 +1,45 @@
-.calendar_onclick_placeholder {
- padding: 0 0 2px 0;
-}
-
-.calendar_commit_activity {
- padding: 5px 0 0;
-}
-
-.calendar_onclick_second {
- font-size: 14px;
- display: block;
-}
-
-.calendar_onclick_hr {
- padding: 0;
- margin: 10px 0;
-}
+.user-calendar-activities {
+
+ .calendar_commit_activity {
+ padding: 5px 0 0;
+ }
+
+ .calendar_onclick_hr {
+ padding: 0;
+ margin: 10px 0;
+ }
+
+ .calendar_commit_date {
+ color: #999;
+ }
+
+ .calendar_activity_summary {
+ font-size: 14px;
+ }
-.calendar_commit_date {
- color: #999;
-}
+ .str-truncated {
+ max-width: 70%;
+ }
-.calendar_activity_summary {
- font-size: 14px;
+ .text-expander {
+ background: #eee;
+ color: #555;
+ padding: 0 5px;
+ cursor: pointer;
+ margin-left: 4px;
+ &:hover {
+ background-color: #ddd;
+ }
+ }
+
+ .commit-row-message {
+ color: #333;
+ &:hover {
+ color: #444;
+ text-decoration: underline;
+ }
+ }
}
-
/**
* This overwrites the default values of the cal-heatmap gem
*/
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index 8a13394dbac..68130eb128c 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -32,6 +32,7 @@ class UsersController < ApplicationController
def calendar
projects = Project.where(id: authorized_projects_ids & @user.contributed_projects_ids)
+
calendar = Gitlab::CommitsCalendar.new(projects, @user)
@timestamps = calendar.timestamps
@starting_year = calendar.starting_year
@@ -40,6 +41,24 @@ class UsersController < ApplicationController
render 'calendar', layout: false
end
+ def calendar_activities
+ projects = Project.where(id: authorized_projects_ids & @user.contributed_projects_ids)
+
+ date = Date.parse(params[:date]) rescue nil
+ if date
+ @calendar_activities = Gitlab::CommitsCalendar.get_commits_for_date(projects, @user, date)
+ else
+ @calendar_activities = {}
+ end
+
+ # get the total number of unique commits
+ @commit_count = @calendar_activities.values.flatten.map(&:id).uniq.count
+
+ @calendar_date = date
+
+ render 'calendar_activities', layout: false
+ end
+
def determine_layout
if current_user
'navless'
diff --git a/app/models/project_contributions.rb b/app/models/project_contributions.rb
index 8ab2d814a94..bfe9928b158 100644
--- a/app/models/project_contributions.rb
+++ b/app/models/project_contributions.rb
@@ -17,6 +17,15 @@ class ProjectContributions
end
end
+ def user_commits_on_date(date)
+ repository = @project.repository
+
+ if !repository.exists? || repository.empty?
+ return []
+ end
+ commits = repository.commits_by_user_on_date_log(@user, date)
+ end
+
def cache_key
"#{Date.today.to_s}-commits-log-#{project.id}-#{user.email}"
end
diff --git a/app/models/repository.rb b/app/models/repository.rb
index 47758b8ad68..7addbca8fb1 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -157,6 +157,20 @@ class Repository
end
end
+ def commits_by_user_on_date_log(user, date)
+ # format the date string for git
+ start_date = date.strftime("%Y-%m-%d 00:00:00")
+ end_date = date.strftime("%Y-%m-%d 23:59:59")
+
+ author_emails = '(' + user.all_emails.map{ |e| Regexp.escape(e) }.join('|') + ')'
+ args = %W(git log -E --author=#{author_emails} --after=#{start_date.to_s} --until=#{end_date.to_s} --branches --pretty=format:%h)
+ commits = Gitlab::Popen.popen(args, path_to_repo).first.split("\n")
+
+ commits.map! do |commit_id|
+ commit(commit_id)
+ end
+ end
+
def commits_per_day_for_user(user)
timestamps_by_user_log(user).
group_by { |commit_date| commit_date }.
diff --git a/app/views/users/calendar.html.haml b/app/views/users/calendar.html.haml
index 1d1c974da24..d113ceeb753 100644
--- a/app/views/users/calendar.html.haml
+++ b/app/views/users/calendar.html.haml
@@ -4,5 +4,6 @@
new calendar(
#{@timestamps.to_json},
#{@starting_year},
- #{@starting_month}
+ #{@starting_month},
+ '#{user_calendar_activities_path}'
);
diff --git a/app/views/users/calendar_activities.html.haml b/app/views/users/calendar_activities.html.haml
new file mode 100644
index 00000000000..7c0cecfadb5
--- /dev/null
+++ b/app/views/users/calendar_activities.html.haml
@@ -0,0 +1,33 @@
+.calendar_commit_activity
+ %hr
+ %h4
+ Commit Activity
+ %strong
+ - if @commit_count == 0
+ no
+ - else
+ = @commit_count
+ %span.calendar_commit_date
+ unique
+ = 'commit'.pluralize(@commit_count)
+ on
+ = @calendar_date.strftime("%b %d, %Y") rescue ''
+ -unless @commit_count == 0
+ %hr
+ - @calendar_activities.each do |project, commits|
+ - next if commits.empty?
+ %div.js-toggle-container
+ %strong
+ = pluralize(commits.count, 'commit')
+ in project
+ = link_to project.name_with_namespace, project_path(project)
+ %a.text-expander.js-toggle-button &hellip;
+ %hr
+ %div.js-toggle-content
+ - commits.each do |commit|
+ %span.monospace
+ = commit.committed_date.strftime("%H:%M")
+ = link_to commit.short_id, namespace_project_commit_path(project.namespace, project, commit), class: "commit_short_id"
+ = link_to commit.message, namespace_project_commit_path(project.namespace, project, commit), class: "commit-row-message str-truncated"
+ %br
+ %hr
diff --git a/app/views/users/show.html.haml b/app/views/users/show.html.haml
index abd6b229782..6d6beb58711 100644
--- a/app/views/users/show.html.haml
+++ b/app/views/users/show.html.haml
@@ -25,6 +25,7 @@
.user-calendar
%h4.center.light
%i.fa.fa-spinner.fa-spin
+ .user-calendar-activities
%hr
%h4
User Activity
diff --git a/config/routes.rb b/config/routes.rb
index e65ef30afb7..0950bed3cf1 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -198,7 +198,10 @@ Gitlab::Application.routes.draw do
end
get 'u/:username/calendar' => 'users#calendar', as: :user_calendar,
- constraints: { username: /(?:[^.]|\.(?!atom$))+/, format: /atom/ }
+ constraints: { username: /.*/ }
+
+ get 'u/:username/calendar_activities' => 'users#calendar_activities', as: :user_calendar_activities,
+ constraints: { username: /.*/ }
get '/u/:username' => 'users#show', as: :user,
constraints: { username: /(?:[^.]|\.(?!atom$))+/, format: /atom/ }
diff --git a/db/schema.rb b/db/schema.rb
index e7dccbad4f9..1be3782dcb3 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -458,7 +458,6 @@ ActiveRecord::Schema.define(version: 20150313012111) do
t.integer "notification_level", default: 1, null: false
t.datetime "password_expires_at"
t.integer "created_by_id"
- t.datetime "last_credential_check_at"
t.string "avatar"
t.string "confirmation_token"
t.datetime "confirmed_at"
@@ -466,6 +465,7 @@ ActiveRecord::Schema.define(version: 20150313012111) do
t.string "unconfirmed_email"
t.boolean "hide_no_ssh_key", default: false
t.string "website_url", default: "", null: false
+ t.datetime "last_credential_check_at"
t.string "github_access_token"
t.string "gitlab_access_token"
t.string "notification_email"
diff --git a/lib/gitlab/commits_calendar.rb b/lib/gitlab/commits_calendar.rb
index 2f30d238e6b..8963d346b6f 100644
--- a/lib/gitlab/commits_calendar.rb
+++ b/lib/gitlab/commits_calendar.rb
@@ -22,6 +22,14 @@ module Gitlab
end
end
+ def self.get_commits_for_date(projects, user, date)
+ user_commits = {}
+ projects.reject(&:forked?).each do |project|
+ user_commits[project] = ProjectContributions.new(project, user).user_commits_on_date(date)
+ end
+ user_commits
+ end
+
def starting_year
(Time.now - 1.year).strftime("%Y")
end
diff --git a/spec/controllers/users_controller_spec.rb b/spec/controllers/users_controller_spec.rb
index 44225c054f2..7962bcdde71 100644
--- a/spec/controllers/users_controller_spec.rb
+++ b/spec/controllers/users_controller_spec.rb
@@ -1,27 +1,59 @@
require 'spec_helper'
describe UsersController do
- let(:user) { create(:user, username: "user1", name: "User 1", email: "user1@gitlab.com") }
+ let(:user) { create(:user, username: 'user1', name: 'User 1', email: 'user1@gitlab.com') }
before do
sign_in(user)
end
- describe "GET #show" do
+ describe 'GET #show' do
render_views
- it "renders the show template" do
+ it 'renders the show template' do
get :show, username: user.username
expect(response.status).to eq(200)
- expect(response).to render_template("show")
+ expect(response).to render_template('show')
end
end
- describe "GET #calendar" do
- it "renders calendar" do
+ describe 'GET #calendar' do
+ it 'renders calendar' do
get :calendar, username: user.username
- expect(response).to render_template("calendar")
+ expect(response).to render_template('calendar')
end
end
-end
+ describe 'GET #calendar_activities' do
+ include RepoHelpers
+ let(:project) { create(:project) }
+ let(:calendar_user) { create(:user, email: sample_commit.author_email) }
+ let(:commit1) { '0ed8c6c6752e8c6ea63e7b92a517bf5ac1209c80' }
+ let(:commit2) { '7d3b0f7cff5f37573aea97cebfd5692ea1689924' }
+
+ before do
+ allow_any_instance_of(User).to receive(:contributed_projects_ids).and_return([project.id])
+ project.team << [user, :developer]
+ end
+
+ it 'assigns @commit_count' do
+ get :calendar_activities, username: calendar_user.username, date: '2014-07-31'
+ expect(assigns(:commit_count)).to eq(2)
+ end
+
+ it 'assigns @calendar_date' do
+ get :calendar_activities, username: calendar_user.username, date: '2014-07-31'
+ expect(assigns(:calendar_date)).to eq(Date.parse('2014-07-31'))
+ end
+
+ it 'assigns @calendar_activities' do
+ get :calendar_activities, username: calendar_user.username, date: '2014-07-31'
+ expect(assigns(:calendar_activities).values.flatten.map(&:id)).to eq([commit1, commit2])
+ end
+
+ it 'renders calendar_activities' do
+ get :calendar_activities, username: calendar_user.username
+ expect(response).to render_template('calendar_activities')
+ end
+ end
+end
diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb
index b3a38f6c5b9..0e3e0b167d7 100644
--- a/spec/models/repository_spec.rb
+++ b/spec/models/repository_spec.rb
@@ -29,7 +29,7 @@ describe Repository do
subject { repository.timestamps_by_user_log(user) }
- it { is_expected.to eq(["2014-08-06", "2014-07-31", "2014-07-31"]) }
+ it { is_expected.to eq(['2014-08-06', '2014-07-31', '2014-07-31']) }
end
describe 'multiple emails for user' do
@@ -38,7 +38,22 @@ describe Repository do
subject { repository.timestamps_by_user_log(user) }
- it { is_expected.to eq(["2015-01-10", "2014-08-06", "2014-07-31", "2014-07-31"]) }
+ it { is_expected.to eq(['2015-01-10', '2014-08-06', '2014-07-31', '2014-07-31']) }
+ end
+ end
+
+ context :commits_by_user_on_date_log do
+
+ describe 'single e-mail for user' do
+ let(:user) { create(:user, email: sample_commit.author_email) }
+ let(:commit1) { '0ed8c6c6752e8c6ea63e7b92a517bf5ac1209c80' }
+ let(:commit2) { '7d3b0f7cff5f37573aea97cebfd5692ea1689924' }
+
+ subject { repository.commits_by_user_on_date_log(user,Date.new(2014, 07, 31)) }
+
+ it 'contains the exepected commits' do
+ expect(subject.flatten.map(&:id)).to eq([commit1, commit2])
+ end
end
end
end