Commit 8a685ca8 authored by Bob Van Landuyt's avatar Bob Van Landuyt

Fix bug with project pagination

When projects were listed after groups, the projects that would also
have been listed on the last page containing groups would be repeated.
parent 9870453e
...@@ -59,8 +59,7 @@ class GroupDescendantsFinder ...@@ -59,8 +59,7 @@ class GroupDescendantsFinder
.page(params[:page]).per(per_page) .page(params[:page]).per(per_page)
.select(GROUP_SELECTS) .select(GROUP_SELECTS)
paginated_projects = projects.with_route.page(subgroup_page - group_page_count) paginated_projects = paginate_projects_after_groups(subgroups_with_counts)
.per(per_page - subgroups_with_counts.size)
if params[:filter] if params[:filter]
ancestors_for_project_search = ancestors_for_groups(Group.where(id: paginated_projects.select(:namespace_id))) ancestors_for_project_search = ancestors_for_groups(Group.where(id: paginated_projects.select(:namespace_id)))
...@@ -70,6 +69,31 @@ class GroupDescendantsFinder ...@@ -70,6 +69,31 @@ class GroupDescendantsFinder
@children = subgroups_with_counts + paginated_projects @children = subgroups_with_counts + paginated_projects
end end
def paginate_projects_after_groups(loaded_subgroups)
# We adjust the pagination for projects for the combination with groups:
# - We limit the first page (page 0) where we show projects:
# Page size = 20: 17 groups, 3 projects
# - We ofset the page to start at 0 after the group pages:
# 3 pages of projects:
# - currently on page 3: Show page 0 (first page) limited to the number of
# projects that still fit the page (no offset)
# - currently on page 4: Show page 1 show all projects, offset by the number
# of projects shown on project-page 0.
group_page_count = loaded_subgroups.total_pages
subgroup_page = loaded_subgroups.current_page
group_last_page_count = subgroups.page(group_page_count).count
project_page = subgroup_page - group_page_count
offset = if project_page.zero? || group_page_count.zero?
0
else
per_page - group_last_page_count
end
projects.with_route.page(project_page)
.per(per_page - loaded_subgroups.size)
.padding(offset)
end
def direct_child_groups def direct_child_groups
GroupsFinder.new(current_user, GroupsFinder.new(current_user,
parent: parent_group, parent: parent_group,
......
...@@ -152,13 +152,15 @@ describe GroupsController do ...@@ -152,13 +152,15 @@ describe GroupsController do
describe 'GET #show' do describe 'GET #show' do
context 'pagination' do context 'pagination' do
let(:per_page) { 3 }
before do before do
allow(Kaminari.config).to receive(:default_per_page).and_return(2) allow(Kaminari.config).to receive(:default_per_page).and_return(per_page)
end end
context 'with only projects' do context 'with only projects' do
let!(:other_project) { create(:project, :public, namespace: group) } let!(:other_project) { create(:project, :public, namespace: group) }
let!(:first_page_projects) { create_list(:project, Kaminari.config.default_per_page, :public, namespace: group ) } let!(:first_page_projects) { create_list(:project, per_page, :public, namespace: group ) }
it 'has projects on the first page' do it 'has projects on the first page' do
get :show, id: group.to_param, sort: 'id_desc' get :show, id: group.to_param, sort: 'id_desc'
...@@ -174,9 +176,9 @@ describe GroupsController do ...@@ -174,9 +176,9 @@ describe GroupsController do
end end
context 'with subgroups and projects', :nested_groups do context 'with subgroups and projects', :nested_groups do
let!(:first_page_subgroups) { create_list(:group, Kaminari.config.default_per_page, parent: group) } let!(:first_page_subgroups) { create_list(:group, per_page, :public, parent: group) }
let!(:other_subgroup) { create(:group, :public, parent: group) } let!(:other_subgroup) { create(:group, :public, parent: group) }
let!(:project) { create(:project, :public, namespace: group) } let!(:next_page_projects) { create_list(:project, per_page, :public, namespace: group) }
it 'contains all subgroups' do it 'contains all subgroups' do
get :children, id: group.to_param, sort: 'id_asc', format: :json get :children, id: group.to_param, sort: 'id_asc', format: :json
...@@ -187,7 +189,7 @@ describe GroupsController do ...@@ -187,7 +189,7 @@ describe GroupsController do
it 'contains the project and group on the second page' do it 'contains the project and group on the second page' do
get :children, id: group.to_param, sort: 'id_asc', page: 2, format: :json get :children, id: group.to_param, sort: 'id_asc', page: 2, format: :json
expect(assigns(:children)).to contain_exactly(other_subgroup, project) expect(assigns(:children)).to contain_exactly(other_subgroup, *next_page_projects.take(per_page - 1))
end end
end end
end end
......
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