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
12e01dae
Commit
12e01dae
authored
6 years ago
by
Heinrich Lee Yu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add group milestones in upcoming filter
parent
c07bf1ab
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
76 additions
and
24 deletions
+76
-24
app/finders/issuable_finder.rb
app/finders/issuable_finder.rb
+17
-3
app/models/milestone.rb
app/models/milestone.rb
+20
-8
spec/finders/issues_finder_spec.rb
spec/finders/issues_finder_spec.rb
+12
-7
spec/models/milestone_spec.rb
spec/models/milestone_spec.rb
+27
-6
No files found.
app/finders/issuable_finder.rb
View file @
12e01dae
...
...
@@ -149,6 +149,18 @@ class IssuableFinder
end
end
def
related_groups
if
project?
&&
project
&&
project
.
group
&&
Ability
.
allowed?
(
current_user
,
:read_group
,
project
.
group
)
project
.
group
.
self_and_ancestors
elsif
group
[
group
]
elsif
current_user
Gitlab
::
GroupHierarchy
.
new
(
current_user
.
authorized_groups
,
current_user
.
groups
).
all_groups
else
[]
end
end
def
project?
params
[
:project_id
].
present?
end
...
...
@@ -163,8 +175,10 @@ class IssuableFinder
end
# rubocop: disable CodeReuse/ActiveRecord
def
projects
(
items
=
nil
)
return
@projects
=
project
if
project?
def
projects
return
@projects
if
defined?
(
@projects
)
return
@projects
=
[
project
]
if
project?
projects
=
if
current_user
&&
params
[
:authorized_only
].
presence
&&
!
current_user_related?
...
...
@@ -459,7 +473,7 @@ class IssuableFinder
elsif
filter_by_any_milestone?
items
=
items
.
any_milestone
elsif
filter_by_upcoming_milestone?
upcoming_ids
=
Milestone
.
upcoming_ids
_by_projects
(
projects
(
items
)
)
upcoming_ids
=
Milestone
.
upcoming_ids
(
projects
,
related_groups
)
items
=
items
.
left_joins_milestones
.
where
(
milestone_id:
upcoming_ids
)
elsif
filter_by_started_milestone?
items
=
items
.
left_joins_milestones
.
where
(
'milestones.start_date <= NOW()'
)
...
...
This diff is collapsed.
Click to expand it.
app/models/milestone.rb
View file @
12e01dae
...
...
@@ -40,6 +40,7 @@ class Milestone < ActiveRecord::Base
scope
:for_projects_and_groups
,
->
(
project_ids
,
group_ids
)
do
conditions
=
[]
conditions
<<
arel_table
[
:project_id
].
in
(
project_ids
)
if
project_ids
&
.
compact
&
.
any?
conditions
<<
arel_table
[
:group_id
].
in
(
group_ids
)
if
group_ids
&
.
compact
&
.
any?
...
...
@@ -129,18 +130,29 @@ class Milestone < ActiveRecord::Base
@link_reference_pattern
||=
super
(
"milestones"
,
/(?<milestone>\d+)/
)
end
def
self
.
upcoming_ids_by_projects
(
projects
)
rel
=
unscoped
.
of_projects
(
projects
).
active
.
where
(
'due_date > ?'
,
Time
.
now
)
def
self
.
upcoming_ids
(
projects
,
groups
)
rel
=
unscoped
.
for_projects_and_groups
(
projects
&
.
map
(
&
:id
),
groups
&
.
map
(
&
:id
))
.
active
.
where
(
'milestones.due_date > NOW()'
)
if
Gitlab
::
Database
.
postgresql?
rel
.
order
(
:project_id
,
:
due_date
).
select
(
'DISTINCT ON (project
_id) id'
)
rel
.
order
(
:project_id
,
:
group_id
,
:due_date
).
select
(
'DISTINCT ON (project_id, group
_id) id'
)
else
# We need to use MySQL's NULL-safe comparison operator `<=>` here
# because one of `project_id` or `group_id` is always NULL
join_clause
=
<<~
HEREDOC
LEFT OUTER JOIN milestones earlier_milestones
ON milestones.project_id <=> earlier_milestones.project_id
AND milestones.group_id <=> earlier_milestones.group_id
AND milestones.due_date > earlier_milestones.due_date
AND earlier_milestones.due_date > NOW()
AND earlier_milestones.state = 'active'
HEREDOC
rel
.
group
(
:project_id
,
:due_date
,
:id
)
.
having
(
'due_date = MIN(due_date)'
)
.
pluck
(
:id
,
:project_id
,
:due_date
)
.
uniq
(
&
:second
)
.
map
(
&
:first
)
.
joins
(
join_clause
)
.
where
(
'earlier_milestones.id IS NULL'
)
.
select
(
:id
)
end
end
...
...
This diff is collapsed.
Click to expand it.
spec/finders/issues_finder_spec.rb
View file @
12e01dae
...
...
@@ -174,9 +174,13 @@ describe IssuesFinder do
context
'filtering by upcoming milestone'
do
let
(
:params
)
{
{
milestone_title:
Milestone
::
Upcoming
.
name
}
}
let!
(
:group
)
{
create
(
:group
,
:public
)
}
let!
(
:group_member
)
{
create
(
:group_member
,
group:
group
,
user:
user
)
}
let
(
:project_no_upcoming_milestones
)
{
create
(
:project
,
:public
)
}
let
(
:project_next_1_1
)
{
create
(
:project
,
:public
)
}
let
(
:project_next_8_8
)
{
create
(
:project
,
:public
)
}
let
(
:project_in_group
)
{
create
(
:project
,
:public
,
namespace:
group
)
}
let
(
:yesterday
)
{
Date
.
today
-
1
.
day
}
let
(
:tomorrow
)
{
Date
.
today
+
1
.
day
}
...
...
@@ -187,21 +191,22 @@ describe IssuesFinder do
[
create
(
:milestone
,
:closed
,
project:
project_no_upcoming_milestones
),
create
(
:milestone
,
project:
project_next_1_1
,
title:
'1.1'
,
due_date:
two_days_from_now
),
create
(
:milestone
,
project:
project_next_1_1
,
title:
'8.8'
,
due_date:
ten_days_from_now
),
create
(
:milestone
,
project:
project_next_8_8
,
title:
'1.1'
,
due_date:
yesterday
),
create
(
:milestone
,
project:
project_next_8_8
,
title:
'8.8'
,
due_date:
tomorrow
)
create
(
:milestone
,
project:
project_next_1_1
,
title:
'8.9'
,
due_date:
ten_days_from_now
),
create
(
:milestone
,
project:
project_next_8_8
,
title:
'1.2'
,
due_date:
yesterday
),
create
(
:milestone
,
project:
project_next_8_8
,
title:
'8.8'
,
due_date:
tomorrow
),
create
(
:milestone
,
group:
group
,
title:
'9.9'
,
due_date:
tomorrow
)
]
end
before
do
milestones
.
each
do
|
milestone
|
create
(
:issue
,
project:
milestone
.
project
,
milestone:
milestone
,
author:
user
,
assignees:
[
user
])
create
(
:issue
,
project:
milestone
.
project
||
project_in_group
,
milestone:
milestone
,
author:
user
,
assignees:
[
user
])
end
end
it
'returns issues in the upcoming milestone for each project'
do
expect
(
issues
.
map
{
|
issue
|
issue
.
milestone
.
title
}).
to
contain_exactly
(
'1.1'
,
'8.8'
)
expect
(
issues
.
map
{
|
issue
|
issue
.
milestone
.
due_date
}).
to
contain_exactly
(
tomorrow
,
two_days_from_now
)
it
'returns issues in the upcoming milestone for each project
or group
'
do
expect
(
issues
.
map
{
|
issue
|
issue
.
milestone
.
title
}).
to
contain_exactly
(
'1.1'
,
'8.8'
,
'9.9'
)
expect
(
issues
.
map
{
|
issue
|
issue
.
milestone
.
due_date
}).
to
contain_exactly
(
tomorrow
,
two_days_from_now
,
tomorrow
)
end
end
...
...
This diff is collapsed.
Click to expand it.
spec/models/milestone_spec.rb
View file @
12e01dae
...
...
@@ -240,7 +240,22 @@ describe Milestone do
end
end
describe
'.upcoming_ids_by_projects'
do
describe
'.upcoming_ids'
do
let
(
:group_1
)
{
create
(
:group
)
}
let
(
:group_2
)
{
create
(
:group
)
}
let
(
:group_3
)
{
create
(
:group
)
}
let
(
:groups
)
{
[
group_1
,
group_2
,
group_3
]
}
let!
(
:past_milestone_group_1
)
{
create
(
:milestone
,
group:
group_1
,
due_date:
Time
.
now
-
1
.
day
)
}
let!
(
:current_milestone_group_1
)
{
create
(
:milestone
,
group:
group_1
,
due_date:
Time
.
now
+
1
.
day
)
}
let!
(
:future_milestone_group_1
)
{
create
(
:milestone
,
group:
group_1
,
due_date:
Time
.
now
+
2
.
days
)
}
let!
(
:past_milestone_group_2
)
{
create
(
:milestone
,
group:
group_2
,
due_date:
Time
.
now
-
1
.
day
)
}
let!
(
:closed_milestone_group_2
)
{
create
(
:milestone
,
:closed
,
group:
group_2
,
due_date:
Time
.
now
+
1
.
day
)
}
let!
(
:current_milestone_group_2
)
{
create
(
:milestone
,
group:
group_2
,
due_date:
Time
.
now
+
2
.
days
)
}
let!
(
:past_milestone_group_3
)
{
create
(
:milestone
,
group:
group_3
,
due_date:
Time
.
now
-
1
.
day
)
}
let
(
:project_1
)
{
create
(
:project
)
}
let
(
:project_2
)
{
create
(
:project
)
}
let
(
:project_3
)
{
create
(
:project
)
}
...
...
@@ -258,14 +273,20 @@ describe Milestone do
# The call to `#try` is because this returns a relation with a Postgres DB,
# and an array of IDs with a MySQL DB.
let
(
:milestone_ids
)
{
described_class
.
upcoming_ids_by_projects
(
projects
).
map
{
|
id
|
id
.
try
(
:id
)
||
id
}
}
it
'returns the next upcoming open milestone ID for each project'
do
expect
(
milestone_ids
).
to
contain_exactly
(
current_milestone_project_1
.
id
,
current_milestone_project_2
.
id
)
let
(
:milestone_ids
)
{
described_class
.
upcoming_ids
(
projects
,
groups
).
map
{
|
id
|
id
.
try
(
:id
)
||
id
}
}
it
'returns the next upcoming open milestone ID for each project and group'
do
expect
(
milestone_ids
).
to
contain_exactly
(
current_milestone_project_1
.
id
,
current_milestone_project_2
.
id
,
current_milestone_group_1
.
id
,
current_milestone_group_2
.
id
)
end
context
'when the projects have no open upcoming milestones'
do
context
'when the projects
and groups
have no open upcoming milestones'
do
let
(
:projects
)
{
[
project_3
]
}
let
(
:groups
)
{
[
group_3
]
}
it
'returns no results'
do
expect
(
milestone_ids
).
to
be_empty
...
...
This diff is collapsed.
Click to expand it.
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