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
b600f42c
Commit
b600f42c
authored
Aug 10, 2018
by
Jarka Kadlecová
Committed by
Jarka Košanová
Sep 05, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add support for sorting epics
parent
9554796e
Changes
18
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
269 additions
and
32 deletions
+269
-32
app/helpers/sorting_helper.rb
app/helpers/sorting_helper.rb
+2
-0
doc/user/group/epics/index.md
doc/user/group/epics/index.md
+1
-1
doc/user/group/roadmap/index.md
doc/user/group/roadmap/index.md
+2
-0
ee/app/controllers/concerns/epics_actions.rb
ee/app/controllers/concerns/epics_actions.rb
+25
-0
ee/app/controllers/groups/epics_controller.rb
ee/app/controllers/groups/epics_controller.rb
+2
-8
ee/app/controllers/groups/roadmap_controller.rb
ee/app/controllers/groups/roadmap_controller.rb
+6
-0
ee/app/helpers/ee/sorting_helper.rb
ee/app/helpers/ee/sorting_helper.rb
+30
-0
ee/app/models/ee/epic.rb
ee/app/models/ee/epic.rb
+12
-2
ee/app/views/groups/roadmap/show.html.haml
ee/app/views/groups/roadmap/show.html.haml
+1
-1
ee/app/views/shared/epic/_sort_dropdown.html.haml
ee/app/views/shared/epic/_sort_dropdown.html.haml
+2
-0
ee/changelogs/unreleased/6494-epics-sort.yml
ee/changelogs/unreleased/6494-epics-sort.yml
+5
-0
ee/spec/controllers/groups/epics_controller_spec.rb
ee/spec/controllers/groups/epics_controller_spec.rb
+7
-0
ee/spec/controllers/groups/roadmap_controller_spec.rb
ee/spec/controllers/groups/roadmap_controller_spec.rb
+42
-0
ee/spec/features/epics/epics_list_spec.rb
ee/spec/features/epics/epics_list_spec.rb
+65
-9
ee/spec/features/groups/group_roadmap_spec.rb
ee/spec/features/groups/group_roadmap_spec.rb
+16
-2
ee/spec/finders/epics_finder_spec.rb
ee/spec/finders/epics_finder_spec.rb
+11
-1
ee/spec/models/epic_spec.rb
ee/spec/models/epic_spec.rb
+34
-8
locale/gitlab.pot
locale/gitlab.pot
+6
-0
No files found.
app/helpers/sorting_helper.rb
View file @
b600f42c
module
SortingHelper
prepend
::
EE
::
SortingHelper
def
sort_options_hash
{
sort_value_created_date
=>
sort_title_created_date
,
...
...
doc/user/group/epics/index.md
View file @
b600f42c
...
...
@@ -77,7 +77,7 @@ It will display a dropdown menu, from which you can add an author. You can also
text to search by epic title or description. When done, press
<kbd>
Enter
</kbd>
on your
keyboard to filter the list.
You can also sort epics list by
**Created date**
or
**Last updated
**
.
You can also sort epics list by
**Created date**
,
**Last updated**
,
**Planned start date**
, or
**Planned finish date
**
.
![
epics sort
](
img/epics_sort.png
)
...
...
doc/user/group/roadmap/index.md
View file @
b600f42c
...
...
@@ -6,6 +6,8 @@ An Epic within a group containing **Planned start date** and/or **Planned finish
can be visualized in a form of a timeline (e.g. a Gantt chart). The Epics Roadmap page
shows such a visualization for all the epics which are under a group and/or its subgroups.
Epics in the view can be sorted by
**Created date**
,
**Last updated**
,
**Planned start date**
, or
**Planned finish date**
.
![
roadmap view
](
img/roadmap_view.png
)
## Timeline duration
...
...
ee/app/controllers/concerns/epics_actions.rb
0 → 100644
View file @
b600f42c
# frozen_string_literal: true
module
EpicsActions
private
def
finder_type
EpicsFinder
end
def
collection_type
@collection_type
||=
'Epic'
end
def
default_sort_order
sort_value_end_date
end
def
update_cookie_value
(
value
)
case
value
when
'start_date_asc'
then
sort_value_start_date
when
'end_date_asc'
then
sort_value_end_date
else
super
(
value
)
end
end
end
ee/app/controllers/groups/epics_controller.rb
View file @
b600f42c
...
...
@@ -4,6 +4,7 @@ class Groups::EpicsController < Groups::ApplicationController
include
ToggleAwardEmoji
include
ToggleSubscriptionAction
include
RendersNotes
include
EpicsActions
before_action
:check_epics_available!
before_action
:epic
,
except:
[
:index
,
:create
]
...
...
@@ -90,14 +91,6 @@ class Groups::EpicsController < Groups::ApplicationController
EpicsFinder
end
def
collection_type
@collection_type
||=
'Epic'
end
# we don't support custom sorting for epics and therefore don't want to use the issuable_sort cookie
def
set_sort_order_from_cookie
end
def
preload_for_collection
@preload_for_collection
||=
[
:group
,
:author
]
end
...
...
@@ -113,6 +106,7 @@ class Groups::EpicsController < Groups::ApplicationController
end
def
filter_params
set_sort_order_from_cookie
super
.
merge
(
start_date:
params
[
:start_date
],
end_date:
params
[
:end_date
])
end
end
ee/app/controllers/groups/roadmap_controller.rb
View file @
b600f42c
module
Groups
class
RoadmapController
<
Groups
::
ApplicationController
include
IssuableCollections
include
EpicsActions
before_action
:check_epics_available!
before_action
:group
before_action
:persist_roadmap_layout
,
only:
[
:show
]
def
show
# show roadmap for a group
set_sort_order_from_cookie
@sort
=
params
[
:sort
]
||
default_sort_order
@epics_count
=
EpicsFinder
.
new
(
current_user
,
group_id:
@group
.
id
).
execute
.
count
end
...
...
ee/app/helpers/ee/sorting_helper.rb
0 → 100644
View file @
b600f42c
# frozen_string_literal: true
module
EE
module
SortingHelper
extend
::
Gitlab
::
Utils
::
Override
override
:sort_options_hash
def
sort_options_hash
{
sort_value_start_date
=>
sort_title_start_date
,
sort_value_end_date
=>
sort_title_end_date
}.
merge
(
super
)
end
def
sort_title_start_date
s_
(
'SortOptions|Planned start date'
)
end
def
sort_title_end_date
s_
(
'SortOptions|Planned finish date'
)
end
def
sort_value_start_date
'start_date_asc'
end
def
sort_value_end_date
'end_date_asc'
end
end
end
ee/app/models/ee/epic.rb
View file @
b600f42c
...
...
@@ -29,6 +29,14 @@ module EE
nulls_first
=
::
Gitlab
::
Database
.
postgresql?
?
'NULLS FIRST'
:
''
reorder
(
"COALESCE(start_date, end_date) ASC
#{
nulls_first
}
"
)
end
scope
:order_start_date_asc
,
->
do
reorder
(
::
Gitlab
::
Database
.
nulls_last_order
(
'start_date'
),
'id DESC'
)
end
scope
:order_end_date_asc
,
->
do
reorder
(
::
Gitlab
::
Database
.
nulls_last_order
(
'end_date'
),
'id DESC'
)
end
end
class_methods
do
...
...
@@ -71,8 +79,10 @@ module EE
end
def
order_by
(
method
)
if
method
.
to_s
==
'start_or_end_date'
order_start_or_end_date_asc
case
method
.
to_s
when
'start_or_end_date'
then
order_start_or_end_date_asc
when
'start_date_asc'
then
order_start_date_asc
when
'end_date_asc'
then
order_end_date_asc
else
super
end
...
...
ee/app/views/groups/roadmap/show.html.haml
View file @
b600f42c
...
...
@@ -7,7 +7,7 @@
-
has_filters_applied
=
params
[
:label_name
].
present?
||
params
[
:author_username
].
present?
||
params
[
:search
].
present?
-
if
@epics_count
!=
0
=
render
'shared/epic/search_bar'
,
type: :epics
,
hide_sort_dropdown:
true
,
show_roadmap_presets:
true
=
render
'shared/epic/search_bar'
,
type: :epics
,
show_roadmap_presets:
true
#js-roadmap
{
data:
{
epics_path:
group_epics_path
(
@group
,
format: :json
),
group_id:
@group
.
id
,
empty_state_illustration:
image_path
(
'illustrations/epics/roadmap.svg'
),
has_filters_applied:
"#{has_filters_applied}"
,
new_epic_endpoint:
group_epics_path
(
@group
),
preset_type:
roadmap_layout
}
}
-
else
...
...
ee/app/views/shared/epic/_sort_dropdown.html.haml
View file @
b600f42c
...
...
@@ -8,3 +8,5 @@
%li
=
sortable_item
(
sort_title_created_date
,
page_filter_path
(
sort:
sort_value_created_date
,
label:
true
),
sorted_by
)
=
sortable_item
(
sort_title_recently_updated
,
page_filter_path
(
sort:
sort_value_recently_updated
,
label:
true
),
sorted_by
)
=
sortable_item
(
sort_title_start_date
,
page_filter_path
(
sort:
sort_value_start_date
,
label:
true
),
sorted_by
)
=
sortable_item
(
sort_title_end_date
,
page_filter_path
(
sort:
sort_value_end_date
,
label:
true
),
sorted_by
)
ee/changelogs/unreleased/6494-epics-sort.yml
0 → 100644
View file @
b600f42c
---
title
:
Add support for sorting epics
merge_request
:
6885
author
:
type
:
added
ee/spec/controllers/groups/epics_controller_spec.rb
View file @
b600f42c
...
...
@@ -57,6 +57,13 @@ describe Groups::EpicsController do
expect
(
response
).
to
have_gitlab_http_status
(
200
)
end
it
'stores sorting param in a cookie'
do
get
:index
,
group_id:
group
,
sort:
'start_date_asc'
expect
(
cookies
[
'epic_sort'
]).
to
eq
(
'start_date_asc'
)
expect
(
response
).
to
have_gitlab_http_status
(
200
)
end
context
'with page param'
do
let
(
:last_page
)
{
group
.
epics
.
page
.
total_pages
}
...
...
ee/spec/controllers/groups/roadmap_controller_spec.rb
0 → 100644
View file @
b600f42c
# frozen_string_literal: true
require
'spec_helper'
describe
Groups
::
RoadmapController
do
let
(
:group
)
{
create
(
:group
,
:private
)
}
let
(
:epic
)
{
create
(
:epic
,
group:
group
)
}
let
(
:user
)
{
create
(
:user
)
}
describe
'#show'
do
before
do
sign_in
(
user
)
group
.
add_developer
(
user
)
end
context
'when epics feature is disabled'
do
it
"returns 404 status"
do
get
:show
,
group_id:
group
expect
(
response
).
to
have_gitlab_http_status
(
404
)
end
end
context
'when epics feature is enabled'
do
before
do
stub_licensed_features
(
epics:
true
)
end
it
"returns 200 status"
do
get
:show
,
group_id:
group
expect
(
response
).
to
have_gitlab_http_status
(
200
)
end
it
'stores sorting param in a cookie'
do
get
:show
,
group_id:
group
,
sort:
'start_date_asc'
expect
(
cookies
[
'epic_sort'
]).
to
eq
(
'start_date_asc'
)
expect
(
response
).
to
have_gitlab_http_status
(
200
)
end
end
end
end
ee/spec/features/epics/epics_list_spec.rb
View file @
b600f42c
...
...
@@ -11,7 +11,9 @@ describe 'epics list', :js do
end
context
'when epics exist for the group'
do
let!
(
:epics
)
{
create_list
(
:epic
,
2
,
group:
group
)
}
let!
(
:epic1
)
{
create
(
:epic
,
group:
group
,
end_date:
10
.
days
.
ago
)
}
let!
(
:epic2
)
{
create
(
:epic
,
group:
group
,
start_date:
2
.
days
.
ago
)
}
let!
(
:epic3
)
{
create
(
:epic
,
group:
group
,
start_date:
10
.
days
.
ago
,
end_date:
5
.
days
.
ago
)
}
before
do
visit
group_epics_path
(
group
)
...
...
@@ -19,7 +21,7 @@ describe 'epics list', :js do
it
'shows the epics in the navigation sidebar'
do
expect
(
first
(
'.nav-sidebar .active a .nav-item-name'
)).
to
have_content
(
'Epics'
)
expect
(
first
(
'.nav-sidebar .active a .count'
)).
to
have_content
(
'
2
'
)
expect
(
first
(
'.nav-sidebar .active a .count'
)).
to
have_content
(
'
3
'
)
end
it
'renders the filtered search bar correctly'
do
...
...
@@ -28,24 +30,78 @@ describe 'epics list', :js do
end
end
it
'renders the list correctly'
do
it
'sorts by end_date ASC by default'
do
expect
(
page
).
to
have_button
(
'Planned finish date'
)
page
.
within
(
'.content-wrapper .content'
)
do
expect
(
find
(
'.top-area'
)).
to
have_content
(
'All 3'
)
page
.
within
(
".issuable-list"
)
do
page
.
within
(
"li:nth-child(1)"
)
do
expect
(
page
).
to
have_content
(
epic1
.
title
)
end
page
.
within
(
"li:nth-child(2)"
)
do
expect
(
page
).
to
have_content
(
epic3
.
title
)
end
page
.
within
(
"li:nth-child(3)"
)
do
expect
(
page
).
to
have_content
(
epic2
.
title
)
end
end
end
end
it
'sorts by the selected value and stores the selection for epic list & roadmap'
do
page
.
within
(
'.epics-other-filters'
)
do
click_button
'Planned finish date'
sort_options
=
find
(
'ul.dropdown-menu-sort li'
).
all
(
'a'
).
collect
(
&
:text
)
expect
(
sort_options
[
0
]).
to
eq
(
'Created date'
)
expect
(
sort_options
[
1
]).
to
eq
(
'Last updated'
)
expect
(
sort_options
[
2
]).
to
eq
(
'Planned start date'
)
expect
(
sort_options
[
3
]).
to
eq
(
'Planned finish date'
)
click_link
'Planned start date'
end
expect
(
page
).
to
have_button
(
'Planned start date'
)
page
.
within
(
'.content-wrapper .content'
)
do
expect
(
find
(
'.top-area'
)).
to
have_content
(
'All 2'
)
within
(
'.issuable-list'
)
do
expect
(
page
).
to
have_content
(
epics
.
first
.
title
)
expect
(
page
).
to
have_content
(
epics
.
second
.
title
)
expect
(
find
(
'.top-area'
)).
to
have_content
(
'All 3'
)
page
.
within
(
".issuable-list"
)
do
page
.
within
(
"li:nth-child(1)"
)
do
expect
(
page
).
to
have_content
(
epic3
.
title
)
end
page
.
within
(
"li:nth-child(2)"
)
do
expect
(
page
).
to
have_content
(
epic2
.
title
)
end
page
.
within
(
"li:nth-child(3)"
)
do
expect
(
page
).
to
have_content
(
epic1
.
title
)
end
end
end
visit
group_epics_path
(
group
)
expect
(
page
).
to
have_button
(
'Planned start date'
)
visit
group_roadmap_path
(
group
)
expect
(
page
).
to
have_button
(
'Planned start date'
)
end
it
'renders the epic detail correctly after clicking the link'
do
page
.
within
(
'.content-wrapper .content .issuable-list'
)
do
click_link
(
epic
s
.
first
.
title
)
click_link
(
epic
1
.
title
)
end
wait_for_requests
expect
(
page
.
find
(
'.issuable-details h2.title'
)).
to
have_content
(
epic
s
.
first
.
title
)
expect
(
page
.
find
(
'.issuable-details h2.title'
)).
to
have_content
(
epic
1
.
title
)
end
end
...
...
ee/spec/features/groups/group_roadmap_spec.rb
View file @
b600f42c
...
...
@@ -43,8 +43,22 @@ describe 'group epic roadmap', :js do
end
it
'renders the filtered search bar correctly'
do
page
.
within
(
'.content-wrapper .content'
)
do
expect
(
page
).
to
have_css
(
'.epics-filters'
)
page
.
within
(
'.content-wrapper .content .epics-filters'
)
do
expect
(
page
).
to
have_css
(
'.filtered-search-box'
)
end
end
it
'renders the sort dropdown correctly'
do
page
.
within
(
'.content-wrapper .content .epics-filters'
)
do
expect
(
page
).
to
have_css
(
'.filter-dropdown-container'
)
find
(
'.dropdown-toggle'
).
click
page
.
within
(
'.dropdown-menu'
)
do
expect
(
page
).
to
have_selector
(
'li a'
,
count:
4
)
expect
(
page
).
to
have_content
(
'Created date'
)
expect
(
page
).
to
have_content
(
'Last updated'
)
expect
(
page
).
to
have_content
(
'Planned start date'
)
expect
(
page
).
to
have_content
(
'Planned finish date'
)
end
end
end
...
...
ee/spec/finders/epics_finder_spec.rb
View file @
b600f42c
...
...
@@ -6,7 +6,7 @@ describe EpicsFinder do
let
(
:group
)
{
create
(
:group
,
:private
)
}
let
(
:another_group
)
{
create
(
:group
)
}
let!
(
:epic1
)
{
create
(
:epic
,
group:
group
,
title:
'This is awesome epic'
,
created_at:
1
.
week
.
ago
)
}
let!
(
:epic2
)
{
create
(
:epic
,
group:
group
,
created_at:
4
.
days
.
ago
,
author:
user
,
start_date:
2
.
days
.
ago
)
}
let!
(
:epic2
)
{
create
(
:epic
,
group:
group
,
created_at:
4
.
days
.
ago
,
author:
user
,
start_date:
2
.
days
.
ago
,
end_date:
3
.
days
.
from_now
)
}
let!
(
:epic3
)
{
create
(
:epic
,
group:
group
,
description:
'not so awesome'
,
start_date:
5
.
days
.
ago
,
end_date:
3
.
days
.
ago
)
}
let!
(
:epic4
)
{
create
(
:epic
,
group:
another_group
)
}
...
...
@@ -61,6 +61,16 @@ describe EpicsFinder do
expect
(
amount
).
to
be
<=
7
end
context
'sorting'
do
it
'sorts correctly when supported sorting param provided'
do
expect
(
epics
(
sort: :start_date_asc
)).
to
eq
([
epic3
,
epic2
,
epic1
])
end
it
'sorts by id when not supported sorting param provided'
do
expect
(
epics
(
sort: :not_supported_param
)).
to
eq
([
epic3
,
epic2
,
epic1
])
end
end
context
'by created_at'
do
it
'returns all epics created before the given date'
do
expect
(
epics
(
created_before:
2
.
days
.
ago
)).
to
contain_exactly
(
epic1
,
epic2
)
...
...
ee/spec/models/epic_spec.rb
View file @
b600f42c
...
...
@@ -30,16 +30,42 @@ describe Epic do
end
end
describe
'.order_start_or_end_date_asc'
do
let
(
:group
)
{
create
(
:group
)
}
describe
'ordering'
do
let!
(
:epic1
)
{
create
(
:epic
,
start_date:
7
.
days
.
ago
,
end_date:
3
.
days
.
ago
,
updated_at:
3
.
days
.
ago
,
created_at:
7
.
days
.
ago
)
}
let!
(
:epic2
)
{
create
(
:epic
,
start_date:
3
.
days
.
ago
,
updated_at:
10
.
days
.
ago
,
created_at:
12
.
days
.
ago
)
}
let!
(
:epic3
)
{
create
(
:epic
,
end_date:
5
.
days
.
ago
,
updated_at:
5
.
days
.
ago
,
created_at:
6
.
days
.
ago
)
}
let!
(
:epic4
)
{
create
(
:epic
)
}
def
epics
(
order_by
)
described_class
.
order_by
(
order_by
)
end
it
'orders by start_or_end_date'
do
expect
(
epics
(
:start_or_end_date
)).
to
eq
([
epic4
,
epic1
,
epic3
,
epic2
])
end
it
'orders by start_date ASC'
do
expect
(
epics
(
:start_date_asc
)).
to
eq
([
epic1
,
epic2
,
epic4
,
epic3
])
end
it
'orders by end_date ASC'
do
expect
(
epics
(
:end_date_asc
)).
to
eq
([
epic3
,
epic1
,
epic4
,
epic2
])
end
it
'orders by updated_at ASC'
do
expect
(
epics
(
:updated_asc
)).
to
eq
([
epic2
,
epic3
,
epic1
,
epic4
])
end
it
'returns epics sorted by start or end date'
do
epic1
=
create
(
:epic
,
group:
group
,
start_date:
7
.
days
.
ago
,
end_date:
3
.
days
.
ago
)
epic2
=
create
(
:epic
,
group:
group
,
start_date:
3
.
days
.
ago
)
epic3
=
create
(
:epic
,
group:
group
,
end_date:
5
.
days
.
ago
)
epic4
=
create
(
:epic
,
group:
group
)
it
'orders by updated_at DESC'
do
expect
(
epics
(
:updated_desc
)).
to
eq
([
epic4
,
epic1
,
epic3
,
epic2
])
end
it
'orders by created_at ASC'
do
expect
(
epics
(
:created_asc
)).
to
eq
([
epic2
,
epic1
,
epic3
,
epic4
])
end
expect
(
described_class
.
order_start_or_end_date_asc
).
to
eq
([
epic4
,
epic1
,
epic3
,
epic2
])
it
'orders by created_at DESC'
do
expect
(
epics
(
:created_desc
)).
to
eq
([
epic4
,
epic3
,
epic1
,
epic2
])
end
end
...
...
locale/gitlab.pot
View file @
b600f42c
...
...
@@ -6744,6 +6744,12 @@ msgstr ""
msgid "SortOptions|Oldest updated"
msgstr ""
msgid "SortOptions|Planned finish date"
msgstr ""
msgid "SortOptions|Planned start date"
msgstr ""
msgid "SortOptions|Popularity"
msgstr ""
...
...
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