Merge branch 'master' of gitlab.com:gitlab-org/gitlab-ce
This commit is contained in:
commit
1646bfc273
16 changed files with 204 additions and 59 deletions
|
@ -1,6 +1,8 @@
|
|||
Please view this file on the master branch, on stable branches it's out of date.
|
||||
|
||||
v 7.10.0 (unreleased)
|
||||
- enable line wrapping per default and remove the checkbox to toggle it (Hannes Rosenögger)
|
||||
- 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)
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
$ ->
|
||||
# Toggle line wrapping in diff.
|
||||
#
|
||||
# %div.diff-file
|
||||
# %input.js-toggle-diff-line-wrap
|
||||
# %td.line_content
|
||||
#
|
||||
$("body").on "click", ".js-toggle-diff-line-wrap", (e) ->
|
||||
diffFile = $(@).closest(".diff-file")
|
||||
if $(@).is(":checked")
|
||||
diffFile.addClass("diff-wrap-lines")
|
||||
else
|
||||
diffFile.removeClass("diff-wrap-lines")
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
@ -1,29 +1,45 @@
|
|||
.calendar_onclick_placeholder {
|
||||
padding: 0 0 2px 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_activity {
|
||||
padding: 5px 0 0;
|
||||
}
|
||||
.str-truncated {
|
||||
max-width: 70%;
|
||||
}
|
||||
|
||||
.calendar_onclick_second {
|
||||
font-size: 14px;
|
||||
display: block;
|
||||
.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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.calendar_onclick_hr {
|
||||
padding: 0;
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.calendar_commit_date {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.calendar_activity_summary {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/**
|
||||
* This overwrites the default values of the cal-heatmap gem
|
||||
*/
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 }.
|
||||
|
|
|
@ -22,11 +22,6 @@
|
|||
|
||||
.diff-btn-group
|
||||
- if blob.text?
|
||||
- unless params[:view] == 'parallel'
|
||||
%label
|
||||
= check_box_tag nil, 1, false, class: 'js-toggle-diff-line-wrap'
|
||||
Wrap text
|
||||
|
||||
= link_to '#', class: 'js-toggle-diff-comments btn btn-sm' do
|
||||
%i.fa.fa-chevron-down
|
||||
Show/Hide comments
|
||||
|
@ -39,7 +34,7 @@
|
|||
|
||||
= view_file_btn(@commit.id, diff_file, project)
|
||||
|
||||
.diff-content
|
||||
.diff-content.diff-wrap-lines
|
||||
-# Skipp all non non-supported blobs
|
||||
- return unless blob.respond_to?('text?')
|
||||
- if blob.text?
|
||||
|
|
|
@ -4,5 +4,6 @@
|
|||
new calendar(
|
||||
#{@timestamps.to_json},
|
||||
#{@starting_year},
|
||||
#{@starting_month}
|
||||
#{@starting_month},
|
||||
'#{user_calendar_activities_path}'
|
||||
);
|
||||
|
|
33
app/views/users/calendar_activities.html.haml
Normal file
33
app/views/users/calendar_activities.html.haml
Normal file
|
@ -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 …
|
||||
%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
|
|
@ -25,6 +25,7 @@
|
|||
.user-calendar
|
||||
%h4.center.light
|
||||
%i.fa.fa-spinner.fa-spin
|
||||
.user-calendar-activities
|
||||
%hr
|
||||
%h4
|
||||
User Activity
|
||||
|
|
|
@ -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/ }
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue