Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
15e02add
Commit
15e02add
authored
May 15, 2020
by
Felipe Artur
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add blocked by issues count on issues metadata
Backend part of showing blocked by issues count on issues list.
parent
1fbf76cc
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
134 additions
and
7 deletions
+134
-7
app/views/shared/_issuable_meta_data.html.haml
app/views/shared/_issuable_meta_data.html.haml
+1
-1
ee/app/models/issue_link.rb
ee/app/models/issue_link.rb
+17
-0
ee/lib/ee/gitlab/issuable_metadata.rb
ee/lib/ee/gitlab/issuable_metadata.rb
+31
-0
ee/spec/lib/ee/gitlab/issuable_metadata_spec.rb
ee/spec/lib/ee/gitlab/issuable_metadata_spec.rb
+52
-0
ee/spec/models/issue_link_spec.rb
ee/spec/models/issue_link_spec.rb
+18
-0
lib/api/entities/issuable_entity.rb
lib/api/entities/issuable_entity.rb
+6
-1
lib/gitlab/issuable_metadata.rb
lib/gitlab/issuable_metadata.rb
+9
-5
No files found.
app/views/shared/_issuable_meta_data.html.haml
View file @
15e02add
...
...
@@ -2,7 +2,7 @@
-
issue_votes
=
@issuable_meta_data
[
issuable
.
id
]
-
upvotes
,
downvotes
=
issue_votes
.
upvotes
,
issue_votes
.
downvotes
-
issuable_path
=
issuable_path
(
issuable
,
anchor:
'notes'
)
-
issuable_mr
=
@issuable_meta_data
[
issuable
.
id
].
merge_requests_count
(
current_user
)
-
issuable_mr
=
@issuable_meta_data
[
issuable
.
id
].
merge_requests_count
-
if
issuable_mr
>
0
%li
.issuable-mr.d-none.d-sm-block.has-tooltip
{
title:
_
(
'Related merge requests'
)
}
...
...
ee/app/models/issue_link.rb
View file @
15e02add
...
...
@@ -65,6 +65,23 @@ class IssueLink < ApplicationRecord
.
joins
(
"INNER JOIN issues ON issues.id = issue_links.
#{
blocking_key
}
"
)
.
where
(
'issues.state_id'
=>
Issuable
::
STATE_ID_MAP
[
:opened
])
end
def
blocking_issues_for_collection
(
issues_ids
)
from_union
([
select
(
'COUNT(*), issue_links.source_id AS blocking_issue_id'
)
.
joins
(
:target
)
.
where
(
issues:
{
state_id:
Issue
.
available_states
[
:opened
]
})
.
where
(
link_type:
TYPE_BLOCKS
)
.
where
(
source_id:
issues_ids
)
.
group
(
:blocking_issue_id
),
select
(
'COUNT(*), issue_links.target_id AS blocking_issue_id'
)
.
joins
(
:source
)
.
where
(
issues:
{
state_id:
Issue
.
available_states
[
:opened
]
})
.
where
(
link_type:
TYPE_IS_BLOCKED_BY
)
.
where
(
target_id:
issues_ids
)
.
group
(
:blocking_issue_id
)
],
remove_duplicates:
false
).
select
(
'blocking_issue_id, SUM(count) AS count'
).
group
(
'blocking_issue_id'
)
end
end
def
check_self_relation
...
...
ee/lib/ee/gitlab/issuable_metadata.rb
0 → 100644
View file @
15e02add
# frozen_string_literal: true
module
EE
module
Gitlab
module
IssuableMetadata
extend
::
Gitlab
::
Utils
::
Override
override
:metadata_for_issuable
def
metadata_for_issuable
(
id
)
return
super
unless
::
Feature
.
enabled?
(
:blocking_issues_counts
)
super
.
tap
do
|
data
|
blocking_count
=
grouped_blocking_issues_count
.
find
do
|
issue_link
|
issue_link
.
blocking_issue_id
==
id
end
data
.
blocking_issues_count
=
blocking_count
.
try
(
:count
).
to_i
end
end
def
grouped_blocking_issues_count
strong_memoize
(
:grouped_blocking_issues_count
)
do
next
IssueLink
.
none
unless
collection_type
==
'Issue'
IssueLink
.
blocking_issues_for_collection
(
issuable_ids
)
end
end
end
end
end
ee/spec/lib/ee/gitlab/issuable_metadata_spec.rb
0 → 100644
View file @
15e02add
# frozen_string_literal: true
require
'spec_helper'
describe
Gitlab
::
IssuableMetadata
do
let_it_be
(
:user
)
{
create
(
:user
)
}
let_it_be
(
:project1
)
{
create
(
:project
,
:public
,
:repository
,
creator:
user
,
namespace:
user
.
namespace
)
}
let_it_be
(
:project2
)
{
create
(
:project
,
:public
,
:repository
,
creator:
user
,
namespace:
user
.
namespace
)
}
context
'issues'
do
# blocked issues
let_it_be
(
:blocked_issue_1
)
{
create
(
:issue
,
author:
user
,
project:
project1
)
}
let_it_be
(
:blocked_issue_2
)
{
create
(
:issue
,
author:
user
,
project:
project2
)
}
let_it_be
(
:blocked_issue_3
)
{
create
(
:issue
,
author:
user
,
project:
project1
)
}
let_it_be
(
:closed_blocked_issue
)
{
create
(
:issue
,
author:
user
,
project:
project2
,
state: :closed
)
}
# blocking issues (as target or source)
let_it_be
(
:blocking_issue_1
)
{
create
(
:issue
,
project:
project1
)
}
let_it_be
(
:blocking_issue_2
)
{
create
(
:issue
,
project:
project2
)
}
before_all
do
create
(
:issue_link
,
source:
blocking_issue_1
,
target:
blocked_issue_1
,
link_type:
IssueLink
::
TYPE_BLOCKS
)
create
(
:issue_link
,
source:
blocking_issue_2
,
target:
blocked_issue_2
,
link_type:
IssueLink
::
TYPE_BLOCKS
)
create
(
:issue_link
,
source:
blocking_issue_1
,
target:
closed_blocked_issue
,
link_type:
IssueLink
::
TYPE_BLOCKS
)
create
(
:issue_link
,
source:
blocked_issue_3
,
target:
blocking_issue_1
,
link_type:
IssueLink
::
TYPE_IS_BLOCKED_BY
)
end
it
'aggregates stats on issues'
do
data
=
described_class
.
new
(
user
,
Issue
.
all
.
limit
(
6
)).
data
# rubocop: disable CodeReuse/ActiveRecord
expect
(
data
.
count
).
to
eq
(
6
)
expect
(
data
[
blocking_issue_1
.
id
].
blocking_issues_count
).
to
eq
(
2
)
expect
(
data
[
blocking_issue_2
.
id
].
blocking_issues_count
).
to
eq
(
1
)
expect
(
data
[
blocked_issue_1
.
id
].
blocking_issues_count
).
to
eq
(
0
)
end
context
'when blocking_issues_counts feature flag is disabled'
do
before
do
stub_feature_flags
(
blocking_issues_counts:
false
)
end
it
'does not return blocking_issues_counts'
do
create
(
:award_emoji
,
:upvote
,
awardable:
blocking_issue_1
)
meta_data
=
described_class
.
new
(
user
,
Issue
.
all
.
limit
(
7
)).
data
# rubocop: disable CodeReuse/ActiveRecord
expect
(
meta_data
.
values
.
map
{
|
value
|
value
.
blocking_issues_count
}.
uniq
).
to
eq
([
nil
])
# Make sure other properties are still being fetched
expect
(
meta_data
[
blocking_issue_1
.
id
].
upvotes
).
to
eq
(
1
)
end
end
end
end
ee/spec/models/issue_link_spec.rb
View file @
15e02add
...
...
@@ -84,4 +84,22 @@ RSpec.describe IssueLink do
expect
(
described_class
.
inverse_link_type
(
'is_blocked_by'
)).
to
eq
'blocks'
end
end
describe
'.blocking_issues_for_collection'
do
it
'returns blocking issues count grouped by issue id'
do
issue_1
=
create
(
:issue
)
issue_2
=
create
(
:issue
)
issue_3
=
create
(
:issue
)
blocking_issue_1
=
create
(
:issue
,
project:
issue_1
.
project
)
blocking_issue_2
=
create
(
:issue
,
project:
issue_2
.
project
)
create
(
:issue_link
,
source:
blocking_issue_1
,
target:
issue_1
,
link_type:
IssueLink
::
TYPE_BLOCKS
)
create
(
:issue_link
,
source:
issue_2
,
target:
blocking_issue_1
,
link_type:
IssueLink
::
TYPE_IS_BLOCKED_BY
)
create
(
:issue_link
,
source:
blocking_issue_2
,
target:
issue_3
,
link_type:
IssueLink
::
TYPE_BLOCKS
)
results
=
described_class
.
blocking_issues_for_collection
([
blocking_issue_1
,
blocking_issue_2
])
expect
(
results
.
find
{
|
link
|
link
.
blocking_issue_id
==
blocking_issue_1
.
id
}.
count
).
to
eq
(
2
)
expect
(
results
.
find
{
|
link
|
link
.
blocking_issue_id
==
blocking_issue_2
.
id
}.
count
).
to
eq
(
1
)
end
end
end
lib/api/entities/issuable_entity.rb
View file @
15e02add
...
...
@@ -11,7 +11,12 @@ module API
# Avoids an N+1 query when metadata is included
def
issuable_metadata
(
subject
,
options
,
method
,
args
=
nil
)
cached_subject
=
options
.
dig
(
:issuable_metadata
,
subject
.
id
)
(
cached_subject
||
subject
).
public_send
(
method
,
*
args
)
# rubocop: disable GitlabSecurity/PublicSend
if
cached_subject
cached_subject
[
method
]
else
subject
.
public_send
(
method
,
*
args
)
# rubocop: disable GitlabSecurity/PublicSend
end
end
end
end
...
...
lib/gitlab/issuable_metadata.rb
View file @
15e02add
...
...
@@ -7,11 +7,13 @@ module Gitlab
# data structure to store issuable meta data like
# upvotes, downvotes, notes and closing merge requests counts for issues and merge requests
# this avoiding n+1 queries when loading issuable collections on frontend
IssuableMeta
=
Struct
.
new
(
:upvotes
,
:downvotes
,
:user_notes_count
,
:mrs_count
)
do
def
merge_requests_count
(
user
=
nil
)
mrs_count
end
end
IssuableMeta
=
Struct
.
new
(
:upvotes
,
:downvotes
,
:user_notes_count
,
:merge_requests_count
,
:blocking_issues_count
# EE-ONLY
)
attr_reader
:current_user
,
:issuable_collection
...
...
@@ -95,3 +97,5 @@ module Gitlab
end
end
end
Gitlab
::
IssuableMetadata
.
prepend_if_ee
(
'EE::Gitlab::IssuableMetadata'
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment