diff options
| -rw-r--r-- | app/controllers/groups/labels_controller.rb | 5 | ||||
| -rw-r--r-- | app/controllers/projects/labels_controller.rb | 7 | ||||
| -rw-r--r-- | app/finders/labels_finder.rb | 6 | ||||
| -rw-r--r-- | app/helpers/sorting_helper.rb | 11 | ||||
| -rw-r--r-- | app/models/label.rb | 3 | ||||
| -rw-r--r-- | app/views/groups/labels/index.html.haml | 1 | ||||
| -rw-r--r-- | app/views/projects/labels/index.html.haml | 1 | ||||
| -rw-r--r-- | app/views/shared/labels/_sort_dropdown.html.haml | 9 | ||||
| -rw-r--r-- | changelogs/unreleased/50835-add-filtering-sorting-for-labels-on-labels-page.yml | 5 | ||||
| -rw-r--r-- | spec/features/groups/labels/sort_labels_spec.rb | 48 | ||||
| -rw-r--r-- | spec/features/projects/labels/sort_labels_spec.rb | 48 | 
11 files changed, 142 insertions, 2 deletions
| diff --git a/app/controllers/groups/labels_controller.rb b/app/controllers/groups/labels_controller.rb index e95123c0933..059cf160fa2 100644 --- a/app/controllers/groups/labels_controller.rb +++ b/app/controllers/groups/labels_controller.rb @@ -12,6 +12,7 @@ class Groups::LabelsController < Groups::ApplicationController        format.html do          @labels = @group.labels            .optionally_search(params[:search]) +          .order_by(sort)            .page(params[:page])        end        format.json do @@ -117,4 +118,8 @@ class Groups::LabelsController < Groups::ApplicationController          include_descendant_groups: params[:include_descendant_groups],          search: params[:search]).execute    end + +  def sort +    @sort ||= params[:sort] || 'name_asc' +  end  end diff --git a/app/controllers/projects/labels_controller.rb b/app/controllers/projects/labels_controller.rb index 8a2bce6e7b5..69332ee2a0e 100644 --- a/app/controllers/projects/labels_controller.rb +++ b/app/controllers/projects/labels_controller.rb @@ -163,7 +163,12 @@ class Projects::LabelsController < Projects::ApplicationController        LabelsFinder.new(current_user,                         project_id: @project.id,                         include_ancestor_groups: params[:include_ancestor_groups], -                       search: params[:search]).execute +                       search: params[:search], +                       sort: sort).execute +  end + +  def sort +    @sort ||= params[:sort] || 'name_asc'    end    def authorize_admin_labels! diff --git a/app/finders/labels_finder.rb b/app/finders/labels_finder.rb index 1d05bf28438..8418577dab2 100644 --- a/app/finders/labels_finder.rb +++ b/app/finders/labels_finder.rb @@ -54,7 +54,11 @@ class LabelsFinder < UnionFinder    end    def sort(items) -    items.reorder(title: :asc) +    if params[:sort] +      items.order_by(params[:sort]) +    else +      items.reorder(title: :asc) +    end    end    def with_title(items) diff --git a/app/helpers/sorting_helper.rb b/app/helpers/sorting_helper.rb index 731b6806b5f..a6e65d30eda 100644 --- a/app/helpers/sorting_helper.rb +++ b/app/helpers/sorting_helper.rb @@ -101,6 +101,17 @@ module SortingHelper      }    end +  def label_sort_options_hash +    { +      sort_value_name => sort_title_name, +      sort_value_name_desc => sort_title_name_desc, +      sort_value_recently_created => sort_title_recently_created, +      sort_value_oldest_created => sort_title_oldest_created, +      sort_value_recently_updated => sort_title_recently_updated, +      sort_value_oldest_updated => sort_title_oldest_updated +    } +  end +    def sortable_item(item, path, sorted_by)      link_to item, path, class: sorted_by == item ? 'is-active' : ''    end diff --git a/app/models/label.rb b/app/models/label.rb index 8db7c3abd10..8dc7ded53ad 100644 --- a/app/models/label.rb +++ b/app/models/label.rb @@ -6,6 +6,7 @@ class Label < ActiveRecord::Base    include Subscribable    include Gitlab::SQL::Pattern    include OptionallySearch +  include Sortable    # Represents a "No Label" state used for filtering Issues and Merge    # Requests that have no label assigned. @@ -41,6 +42,8 @@ class Label < ActiveRecord::Base    scope :with_lists_and_board, -> { joins(lists: :board).merge(List.movable) }    scope :on_group_boards, ->(group_id) { with_lists_and_board.where(boards: { group_id: group_id }) }    scope :on_project_boards, ->(project_id) { with_lists_and_board.where(boards: { project_id: project_id }) } +  scope :order_name_asc, -> { reorder(title: :asc) } +  scope :order_name_desc, -> { reorder(title: :desc) }    def self.prioritized(project)      joins(:priorities) diff --git a/app/views/groups/labels/index.html.haml b/app/views/groups/labels/index.html.haml index e6821009d03..86178eb2ffd 100644 --- a/app/views/groups/labels/index.html.haml +++ b/app/views/groups/labels/index.html.haml @@ -22,6 +22,7 @@              %span.input-group-append                %button.btn.btn-default{ type: "submit", "aria-label" => _('Submit search') }                  = icon("search") +        = render 'shared/labels/sort_dropdown'      .labels-container.prepend-top-5        - if @labels.any? diff --git a/app/views/projects/labels/index.html.haml b/app/views/projects/labels/index.html.haml index dfac62e7985..1bfd8a85f0f 100644 --- a/app/views/projects/labels/index.html.haml +++ b/app/views/projects/labels/index.html.haml @@ -22,6 +22,7 @@              %span.input-group-append                %button.btn.btn-default{ type: "submit", "aria-label" => _('Submit search') }                  = icon("search") +        = render 'shared/labels/sort_dropdown'      .labels-container.prepend-top-10        - if can_admin_label diff --git a/app/views/shared/labels/_sort_dropdown.html.haml b/app/views/shared/labels/_sort_dropdown.html.haml new file mode 100644 index 00000000000..ff6e2947ffd --- /dev/null +++ b/app/views/shared/labels/_sort_dropdown.html.haml @@ -0,0 +1,9 @@ +- sort_title = label_sort_options_hash[@sort] || sort_title_name_desc +.dropdown.inline +  %button.dropdown-toggle{ type: 'button', data: { toggle: 'dropdown' } } +    = sort_title +    = icon('chevron-down') +  %ul.dropdown-menu.dropdown-menu-right.dropdown-menu-sort +    %li +      - label_sort_options_hash.each do |value, title| +        = sortable_item(title, page_filter_path(sort: value, label: true), sort_title) diff --git a/changelogs/unreleased/50835-add-filtering-sorting-for-labels-on-labels-page.yml b/changelogs/unreleased/50835-add-filtering-sorting-for-labels-on-labels-page.yml new file mode 100644 index 00000000000..24e231ed88a --- /dev/null +++ b/changelogs/unreleased/50835-add-filtering-sorting-for-labels-on-labels-page.yml @@ -0,0 +1,5 @@ +--- +title: Add sorting for labels on labels page +merge_request: 21642 +author: +type: added diff --git a/spec/features/groups/labels/sort_labels_spec.rb b/spec/features/groups/labels/sort_labels_spec.rb new file mode 100644 index 00000000000..2aea4d77675 --- /dev/null +++ b/spec/features/groups/labels/sort_labels_spec.rb @@ -0,0 +1,48 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'Sort labels', :js do +  let(:user) { create(:user) } +  let(:group) { create(:group) } +  let!(:label1) { create(:group_label, title: 'Foo', description: 'Lorem ipsum', group: group) } +  let!(:label2) { create(:group_label, title: 'Bar', description: 'Fusce consequat', group: group) } + +  before do +    group.add_maintainer(user) +    sign_in(user) + +    visit group_labels_path(group) +  end + +  it 'sorts by title by default' do +    expect(page).to have_button('Name') + +    # assert default sorting +    within '.other-labels' do +      expect(page.all('.label-list-item').first.text).to include('Bar') +      expect(page.all('.label-list-item').last.text).to include('Foo') +    end +  end + +  it 'sorts by date' do +    click_button 'Name' + +    sort_options = find('ul.dropdown-menu-sort li').all('a').collect(&:text) + +    expect(sort_options[0]).to eq('Name') +    expect(sort_options[1]).to eq('Name, descending') +    expect(sort_options[2]).to eq('Last created') +    expect(sort_options[3]).to eq('Oldest created') +    expect(sort_options[4]).to eq('Last updated') +    expect(sort_options[5]).to eq('Oldest updated') + +    click_link 'Name, descending' + +    # assert default sorting +    within '.other-labels' do +      expect(page.all('.label-list-item').first.text).to include('Foo') +      expect(page.all('.label-list-item').last.text).to include('Bar') +    end +  end +end diff --git a/spec/features/projects/labels/sort_labels_spec.rb b/spec/features/projects/labels/sort_labels_spec.rb new file mode 100644 index 00000000000..01c3f251173 --- /dev/null +++ b/spec/features/projects/labels/sort_labels_spec.rb @@ -0,0 +1,48 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'Sort labels', :js do +  let(:user) { create(:user) } +  let(:project) { create(:project) } +  let!(:label1) { create(:label, title: 'Foo', description: 'Lorem ipsum', project: project) } +  let!(:label2) { create(:label, title: 'Bar', description: 'Fusce consequat', project: project) } + +  before do +    project.add_maintainer(user) +    sign_in(user) + +    visit project_labels_path(project) +  end + +  it 'sorts by title by default' do +    expect(page).to have_button('Name') + +    # assert default sorting +    within '.other-labels' do +      expect(page.all('.label-list-item').first.text).to include('Bar') +      expect(page.all('.label-list-item').last.text).to include('Foo') +    end +  end + +  it 'sorts by date' do +    click_button 'Name' + +    sort_options = find('ul.dropdown-menu-sort li').all('a').collect(&:text) + +    expect(sort_options[0]).to eq('Name') +    expect(sort_options[1]).to eq('Name, descending') +    expect(sort_options[2]).to eq('Last created') +    expect(sort_options[3]).to eq('Oldest created') +    expect(sort_options[4]).to eq('Last updated') +    expect(sort_options[5]).to eq('Oldest updated') + +    click_link 'Name, descending' + +    # assert default sorting +    within '.other-labels' do +      expect(page.all('.label-list-item').first.text).to include('Foo') +      expect(page.all('.label-list-item').last.text).to include('Bar') +    end +  end +end | 
