diff --git a/app/finders/admin/projects_finder.rb b/app/finders/admin/projects_finder.rb index eac35ae028176e7821f58f600d68c100e4134c03..d6bcd93952211e1c77fa3f2daedc32f6d3faf681 100644 --- a/app/finders/admin/projects_finder.rb +++ b/app/finders/admin/projects_finder.rb @@ -43,7 +43,13 @@ class Admin::ProjectsFinder end def by_archived(items) - items.non_archived unless params[:archived].present? + if params[:archived] == 'only' + items.archived + elsif params[:archived].blank? + items.non_archived + else + items + end end def by_personal(items) diff --git a/app/finders/projects_finder.rb b/app/finders/projects_finder.rb index aa80dfc3f378aa5668d822989ab8f5b08485cfb4..fa6fea2588a2a63345d5181867728ca63817da51 100644 --- a/app/finders/projects_finder.rb +++ b/app/finders/projects_finder.rb @@ -125,9 +125,18 @@ class ProjectsFinder < UnionFinder end def by_archived(projects) - # Back-compatibility with the places where `params[:archived]` can be set explicitly to `false` - params[:non_archived] = !Gitlab::Utils.to_boolean(params[:archived]) if params.key?(:archived) - - params[:non_archived] ? projects.non_archived : projects + if params[:non_archived] + projects.non_archived + elsif params.key?(:archived) # Back-compatibility with the places where `params[:archived]` can be set explicitly to `false` + if params[:archived] == 'only' + projects.archived + elsif Gitlab::Utils.to_boolean(params[:archived]) + projects + else + projects.non_archived + end + else + projects + end end end diff --git a/app/models/project.rb b/app/models/project.rb index 3118a480f7bd40ff3d8225253c28be1a5c9942e3..9d5a56db026584cc0279f21520445d6ea8d7d860 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -247,6 +247,7 @@ class Project < ActiveRecord::Base scope :joined, ->(user) { where('namespace_id != ?', user.namespace_id) } scope :starred_by, ->(user) { joins(:users_star_projects).where('users_star_projects.user_id': user.id) } scope :visible_to_user, ->(user) { where(id: user.authorized_projects.select(:id).reorder(nil)) } + scope :archived, -> { where(archived: true) } scope :non_archived, -> { where(archived: false) } scope :for_milestones, ->(ids) { joins(:milestones).where('milestones.id' => ids).distinct } scope :with_push, -> { joins(:events).where('events.action = ?', Event::PUSHED) } diff --git a/app/views/shared/projects/_dropdown.html.haml b/app/views/shared/projects/_dropdown.html.haml index 8939aeb6c3a91266f8862a551ef52fa4bac3f3b7..80432a73e4e1a5355a6d52ac25dd268ee2b63355 100644 --- a/app/views/shared/projects/_dropdown.html.haml +++ b/app/views/shared/projects/_dropdown.html.haml @@ -15,8 +15,11 @@ = link_to filter_projects_path(archived: nil), class: ("is-active" unless params[:archived].present?) do Hide archived projects %li - = link_to filter_projects_path(archived: true), class: ("is-active" if params[:archived].present?) do + = link_to filter_projects_path(archived: true), class: ("is-active" if Gitlab::Utils.to_boolean(params[:archived])) do Show archived projects + %li + = link_to filter_projects_path(archived: 'only'), class: ("is-active" if params[:archived] == 'only') do + Show archived projects only - if current_user %li.divider %li diff --git a/changelogs/unreleased/35994-archived-projects-only.yml b/changelogs/unreleased/35994-archived-projects-only.yml new file mode 100644 index 0000000000000000000000000000000000000000..ce565b177d01dad7aa21bcc09b9d921b07eca13e --- /dev/null +++ b/changelogs/unreleased/35994-archived-projects-only.yml @@ -0,0 +1,5 @@ +--- +title: Add an option to list only archived projects +merge_request: 13492 +author: Mehdi Lahmam (@mehlah) +type: added diff --git a/spec/features/admin/admin_projects_spec.rb b/spec/features/admin/admin_projects_spec.rb index 77710f80036710c3d2f090b55c980931f0c3b070..f4f2505d4360eba83f57aaa7971050a5464904f2 100644 --- a/spec/features/admin/admin_projects_spec.rb +++ b/spec/features/admin/admin_projects_spec.rb @@ -36,6 +36,14 @@ describe "Admin::Projects" do expect(page).to have_content(archived_project.name) expect(page).to have_xpath("//span[@class='label label-warning']", text: 'archived') end + + it 'renders only archived projects', js: true do + find(:css, '#sort-projects-dropdown').click + click_link 'Show archived projects only' + + expect(page).to have_content(archived_project.name) + expect(page).not_to have_content(project.name) + end end describe "GET /admin/projects/:namespace_id/:id" do diff --git a/spec/features/dashboard/archived_projects_spec.rb b/spec/features/dashboard/archived_projects_spec.rb index 814ec0e59c7fe0fac443dbbdbe51872da0626ee6..e8d699ff5e0fbbc669f3b03bbeb0395313a49e36 100644 --- a/spec/features/dashboard/archived_projects_spec.rb +++ b/spec/features/dashboard/archived_projects_spec.rb @@ -26,6 +26,13 @@ RSpec.describe 'Dashboard Archived Project' do expect(page).to have_link(archived_project.name) end + it 'renders only archived projects' do + click_link 'Show archived projects only' + + expect(page).to have_content(archived_project.name) + expect(page).not_to have_content(project.name) + end + it 'searchs archived projects', :js do click_button 'Last updated' click_link 'Show archived projects' diff --git a/spec/finders/admin/projects_finder_spec.rb b/spec/finders/admin/projects_finder_spec.rb index 28e36330029186a8c8a46c478b06acbf761e3b47..4b67203a0df64611d9792c501b42730cf6c347ac 100644 --- a/spec/finders/admin/projects_finder_spec.rb +++ b/spec/finders/admin/projects_finder_spec.rb @@ -118,6 +118,12 @@ describe Admin::ProjectsFinder do it { is_expected.to match_array([archived_project, shared_project, public_project, internal_project, private_project]) } end + + context 'archived=only' do + let(:params) { { archived: 'only' } } + + it { is_expected.to eq([archived_project]) } + end end context 'filter by personal' do diff --git a/spec/finders/projects_finder_spec.rb b/spec/finders/projects_finder_spec.rb index a5de586e86994f77fb49c6201024ed415c21cd8b..0dfe6ba9c323922478fb2a9c4bf31087a51b3019 100644 --- a/spec/finders/projects_finder_spec.rb +++ b/spec/finders/projects_finder_spec.rb @@ -123,6 +123,12 @@ describe ProjectsFinder do it { is_expected.to match_array([public_project, internal_project, archived_project]) } end + describe 'filter by archived only' do + let(:params) { { archived: 'only' } } + + it { is_expected.to eq([archived_project]) } + end + describe 'filter by archived for backward compatibility' do let(:params) { { archived: false } }