Commit 2e182714 authored by Douglas Barbosa Alexandre's avatar Douglas Barbosa Alexandre

Merge branch '7168-add-mr-approvals-to-contribution-analytics' into 'master'

Add approved MRs count to contribution analytics

Closes #7168

See merge request gitlab-org/gitlab!33601
parents 99aa9c9d 979c9ac4
...@@ -21,6 +21,7 @@ export default { ...@@ -21,6 +21,7 @@ export default {
<td>{{ row.issuesCreated }}</td> <td>{{ row.issuesCreated }}</td>
<td>{{ row.issuesClosed }}</td> <td>{{ row.issuesClosed }}</td>
<td>{{ row.mergeRequestsCreated }}</td> <td>{{ row.mergeRequestsCreated }}</td>
<td>{{ row.mergeRequestsApproved }}</td>
<td>{{ row.mergeRequestsMerged }}</td> <td>{{ row.mergeRequestsMerged }}</td>
<td>{{ row.totalEvents }}</td> <td>{{ row.totalEvents }}</td>
</tr> </tr>
......
...@@ -6,6 +6,7 @@ const COLUMNS = [ ...@@ -6,6 +6,7 @@ const COLUMNS = [
{ name: 'issuesCreated', text: __('Opened issues') }, { name: 'issuesCreated', text: __('Opened issues') },
{ name: 'issuesClosed', text: __('Closed issues') }, { name: 'issuesClosed', text: __('Closed issues') },
{ name: 'mergeRequestsCreated', text: __('Opened MRs') }, { name: 'mergeRequestsCreated', text: __('Opened MRs') },
{ name: 'mergeRequestsApproved', text: __('Approved MRs') },
{ name: 'mergeRequestsMerged', text: __('Merged MRs') }, { name: 'mergeRequestsMerged', text: __('Merged MRs') },
{ name: 'totalEvents', text: __('Total Contributions') }, { name: 'totalEvents', text: __('Total Contributions') },
]; ];
......
---
title: Add MR approval stats to group contribution analytics
merge_request: 33601
author:
type: added
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
module Gitlab module Gitlab
module ContributionAnalytics module ContributionAnalytics
class DataCollector class DataCollector
EVENT_TYPES = %i[push issues_created issues_closed merge_requests_created merge_requests_merged total_events].freeze EVENT_TYPES = %i[push issues_created issues_closed merge_requests_created merge_requests_merged merge_requests_approved total_events].freeze
attr_reader :group, :from attr_reader :group, :from
...@@ -44,6 +44,12 @@ module Gitlab ...@@ -44,6 +44,12 @@ module Gitlab
end end
end end
def merge_requests_approved_by_author_count
all_counts.each_with_object({}) do |(event, count), hash|
hash[event.author_id] = count if event.merge_request? && event.approved_action?
end
end
def total_events_by_author_count def total_events_by_author_count
all_counts.each_with_object({}) do |(event, count), hash| all_counts.each_with_object({}) do |(event, count), hash|
hash[event.author_id] ||= 0 hash[event.author_id] ||= 0
...@@ -71,6 +77,10 @@ module Gitlab ...@@ -71,6 +77,10 @@ module Gitlab
all_counts.sum { |event, count| event.merge_request? && event.merged_action? ? count : 0 } all_counts.sum { |event, count| event.merge_request? && event.merged_action? ? count : 0 }
end end
def total_merge_requests_approved_count
all_counts.sum { |event, count| event.merge_request? && event.approved_action? ? count : 0 }
end
def total_issues_created_count def total_issues_created_count
all_counts.sum { |event, count| event.issue? && event.created_action? ? count : 0 } all_counts.sum { |event, count| event.issue? && event.created_action? ? count : 0 }
end end
...@@ -103,6 +113,7 @@ module Gitlab ...@@ -103,6 +113,7 @@ module Gitlab
issues_closed: issues_closed_by_author_count, issues_closed: issues_closed_by_author_count,
merge_requests_created: merge_requests_created_by_author_count, merge_requests_created: merge_requests_created_by_author_count,
merge_requests_merged: merge_requests_merged_by_author_count, merge_requests_merged: merge_requests_merged_by_author_count,
merge_requests_approved: merge_requests_approved_by_author_count,
total_events: total_events_by_author_count total_events: total_events_by_author_count
} }
end end
...@@ -113,7 +124,7 @@ module Gitlab ...@@ -113,7 +124,7 @@ module Gitlab
def base_query def base_query
Event Event
.where(action: :pushed).or( .where(action: :pushed).or(
Event.where(target_type: [::MergeRequest.name, ::Issue.name], action: [:created, :closed, :merged]) Event.where(target_type: [::MergeRequest.name, ::Issue.name], action: [:created, :closed, :merged, :approved])
) )
.where(Event.arel_table[:created_at].gteq(from)) .where(Event.arel_table[:created_at].gteq(from))
.joins(:project) .joins(:project)
......
...@@ -33,7 +33,7 @@ describe('TableBodyComponent', () => { ...@@ -33,7 +33,7 @@ describe('TableBodyComponent', () => {
const rowEl = vm.$el.querySelector('tr'); const rowEl = vm.$el.querySelector('tr');
expect(rowEl).not.toBeNull(); expect(rowEl).not.toBeNull();
expect(rowEl.querySelectorAll('td')).toHaveLength(7); expect(rowEl.querySelectorAll('td')).toHaveLength(8);
}); });
it('renders username row cell element', () => { it('renders username row cell element', () => {
......
...@@ -41,6 +41,7 @@ export const mockSortOrders = { ...@@ -41,6 +41,7 @@ export const mockSortOrders = {
issuesClosed: 1, issuesClosed: 1,
issuesCreated: 1, issuesCreated: 1,
mergeRequestsCreated: 1, mergeRequestsCreated: 1,
mergeRequestsApproved: 1,
mergeRequestsMerged: 1, mergeRequestsMerged: 1,
push: 1, push: 1,
totalEvents: 1, totalEvents: 1,
......
...@@ -15,6 +15,7 @@ RSpec.describe Gitlab::ContributionAnalytics::DataCollector do ...@@ -15,6 +15,7 @@ RSpec.describe Gitlab::ContributionAnalytics::DataCollector do
create(:event, :closed, project: project1, target: issue, author: user) create(:event, :closed, project: project1, target: issue, author: user)
create(:event, :created, project: project2, target: mr, author: user) create(:event, :created, project: project2, target: mr, author: user)
create(:event, :approved, project: project2, target: mr, author: user)
data_collector = described_class.new(group: group) data_collector = described_class.new(group: group)
expect(data_collector.totals).to eq({ expect(data_collector.totals).to eq({
...@@ -22,8 +23,9 @@ RSpec.describe Gitlab::ContributionAnalytics::DataCollector do ...@@ -22,8 +23,9 @@ RSpec.describe Gitlab::ContributionAnalytics::DataCollector do
issues_created: {}, issues_created: {},
merge_requests_created: { user.id => 1 }, merge_requests_created: { user.id => 1 },
merge_requests_merged: {}, merge_requests_merged: {},
merge_requests_approved: { user.id => 1 },
push: {}, push: {},
total_events: { user.id => 2 } total_events: { user.id => 3 }
}) })
end end
end end
...@@ -37,6 +39,7 @@ RSpec.describe Gitlab::ContributionAnalytics::DataCollector do ...@@ -37,6 +39,7 @@ RSpec.describe Gitlab::ContributionAnalytics::DataCollector do
[4, MergeRequest.name, Event.actions[:merged]] => 2, [4, MergeRequest.name, Event.actions[:merged]] => 2,
[5, MergeRequest.name, Event.actions[:created]] => 0, [5, MergeRequest.name, Event.actions[:created]] => 0,
[6, MergeRequest.name, Event.actions[:created]] => 1, [6, MergeRequest.name, Event.actions[:created]] => 1,
[6, MergeRequest.name, Event.actions[:approved]] => 1,
[10, Issue.name, Event.actions[:closed]] => 10, [10, Issue.name, Event.actions[:closed]] => 10,
[11, Issue.name, Event.actions[:closed]] => 11 [11, Issue.name, Event.actions[:closed]] => 11
} }
...@@ -68,6 +71,10 @@ RSpec.describe Gitlab::ContributionAnalytics::DataCollector do ...@@ -68,6 +71,10 @@ RSpec.describe Gitlab::ContributionAnalytics::DataCollector do
expect(data_collector.total_merge_requests_merged_count).to eq(4) expect(data_collector.total_merge_requests_merged_count).to eq(4)
end end
it 'for #total_merge_requests_approved_count' do
expect(data_collector.total_merge_requests_approved_count).to eq(1)
end
it 'for #total_issues_closed_count' do it 'for #total_issues_closed_count' do
expect(data_collector.total_issues_closed_count).to eq(21) expect(data_collector.total_issues_closed_count).to eq(21)
end end
...@@ -80,6 +87,7 @@ RSpec.describe Gitlab::ContributionAnalytics::DataCollector do ...@@ -80,6 +87,7 @@ RSpec.describe Gitlab::ContributionAnalytics::DataCollector do
expect(data_collector.total_push_count).to eq(0) expect(data_collector.total_push_count).to eq(0)
expect(data_collector.total_merge_requests_created_count).to eq(0) expect(data_collector.total_merge_requests_created_count).to eq(0)
expect(data_collector.total_merge_requests_merged_count).to eq(0) expect(data_collector.total_merge_requests_merged_count).to eq(0)
expect(data_collector.total_merge_requests_approved_count).to eq(0)
expect(data_collector.total_issues_closed_count).to eq(0) expect(data_collector.total_issues_closed_count).to eq(0)
end end
end end
......
...@@ -11,6 +11,7 @@ RSpec.describe UserAnalyticsEntity do ...@@ -11,6 +11,7 @@ RSpec.describe UserAnalyticsEntity do
issues_closed: {}, issues_closed: {},
merge_requests_created: {}, merge_requests_created: {},
merge_requests_merged: {}, merge_requests_merged: {},
merge_requests_approved: {},
total_events: {} total_events: {}
} }
end end
...@@ -23,7 +24,7 @@ RSpec.describe UserAnalyticsEntity do ...@@ -23,7 +24,7 @@ RSpec.describe UserAnalyticsEntity do
end end
[:push, :issues_created, :issues_closed, :merge_requests_created, [:push, :issues_created, :issues_closed, :merge_requests_created,
:merge_requests_merged, :total_events].each do |event_type| :merge_requests_merged, :merge_requests_approved, :total_events].each do |event_type|
it "fetches #{event_type} events for the user from the request" do it "fetches #{event_type} events for the user from the request" do
events[event_type] = { user.id => 42 } events[event_type] = { user.id => 42 }
......
...@@ -2658,6 +2658,9 @@ msgstr "" ...@@ -2658,6 +2658,9 @@ msgstr ""
msgid "Approved" msgid "Approved"
msgstr "" msgstr ""
msgid "Approved MRs"
msgstr ""
msgid "Approved by: " msgid "Approved by: "
msgstr "" msgstr ""
......
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