From 3a69dd20a1d8e54c25f871f35f09a1b8b5d4b2a4 Mon Sep 17 00:00:00 2001
From: Douwe Maan <douwe@gitlab.com>
Date: Wed, 14 Oct 2015 12:33:39 +0200
Subject: [PATCH] Allow dashboard and group issues/MRs to be filtered by label

---
 CHANGELOG                                   |  1 +
 app/helpers/labels_helper.rb                | 18 ++++++++++----
 app/models/group_label.rb                   |  9 +++++++
 app/models/group_milestone.rb               | 12 ++--------
 app/services/labels/group_service.rb        | 26 +++++++++++++++++++++
 app/views/shared/issuable/_filter.html.haml |  9 ++++---
 6 files changed, 55 insertions(+), 20 deletions(-)
 create mode 100644 app/models/group_label.rb
 create mode 100644 app/services/labels/group_service.rb

diff --git a/CHANGELOG b/CHANGELOG
index a3d796bea66..0a0afb4a053 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -45,6 +45,7 @@ v 8.1.0 (unreleased)
   - Fix position of hamburger in header for smaller screens (Han Loong Liauw)
   - Fix bug where Emojis in Markdown would truncate remaining text (Sakata Sinji)
   - Persist filters when sorting on admin user page (Jerry Lukins)
+  - Allow dashboard and group issues/MRs to be filtered by label
 
 v 8.0.4
   - Fix Message-ID header to be RFC 2111-compliant to prevent e-mails being dropped (Stan Hu)
diff --git a/app/helpers/labels_helper.rb b/app/helpers/labels_helper.rb
index 66b18eea699..ee04ace35d0 100644
--- a/app/helpers/labels_helper.rb
+++ b/app/helpers/labels_helper.rb
@@ -92,11 +92,19 @@ module LabelsHelper
     end
   end
 
-  def project_labels_options(project)
-    labels = project.labels.to_a
-    labels.unshift(Label::None)
-    labels.unshift(Label::Any)
-    options_from_collection_for_select(labels, 'name', 'title', params[:label_name])
+  def projects_labels_options
+    labels =
+      if @project
+        @project.labels
+      else
+        Label.where(project_id: @projects)
+      end
+
+    grouped_labels = Labels::GroupService.new(labels).execute
+    grouped_labels.unshift(Label::None)
+    grouped_labels.unshift(Label::Any)
+
+    options_from_collection_for_select(grouped_labels, 'name', 'title', params[:label_name])
   end
 
   # Required for Gitlab::Markdown::LabelReferenceFilter
diff --git a/app/models/group_label.rb b/app/models/group_label.rb
new file mode 100644
index 00000000000..0fc39cb8771
--- /dev/null
+++ b/app/models/group_label.rb
@@ -0,0 +1,9 @@
+class GroupLabel
+  attr_accessor :title, :labels
+  alias_attribute :name, :title
+
+  def initialize(title, labels)
+    @title = title
+    @labels = labels
+  end
+end
diff --git a/app/models/group_milestone.rb b/app/models/group_milestone.rb
index 1dd2be68ebf..91844da62e2 100644
--- a/app/models/group_milestone.rb
+++ b/app/models/group_milestone.rb
@@ -1,5 +1,5 @@
 class GroupMilestone
-
+  attr_accessor :title, :milestones
   alias_attribute :name, :title
 
   def initialize(title, milestones)
@@ -7,18 +7,10 @@ class GroupMilestone
     @milestones = milestones
   end
 
-  def title
-    @title
-  end
-
   def safe_title
     @title.parameterize
   end
-
-  def milestones
-    @milestones
-  end
-
+  
   def projects
     milestones.map { |milestone| milestone.project }
   end
diff --git a/app/services/labels/group_service.rb b/app/services/labels/group_service.rb
new file mode 100644
index 00000000000..b26cee24d56
--- /dev/null
+++ b/app/services/labels/group_service.rb
@@ -0,0 +1,26 @@
+module Labels
+  class GroupService < ::BaseService
+    def initialize(project_labels)
+      @project_labels = project_labels.group_by(&:title)
+    end
+
+    def execute
+      build(@project_labels)
+    end
+
+    def label(title)
+      if title
+        group_label = @project_labels[title].group_by(&:title)
+        build(group_label).first
+      else
+        nil
+      end
+    end
+
+    private
+
+    def build(label)
+      label.map { |title, labels| GroupLabel.new(title, labels) }
+    end
+  end
+end
diff --git a/app/views/shared/issuable/_filter.html.haml b/app/views/shared/issuable/_filter.html.haml
index 8f16773077e..0e4e9c0987a 100644
--- a/app/views/shared/issuable/_filter.html.haml
+++ b/app/views/shared/issuable/_filter.html.haml
@@ -42,11 +42,10 @@
             class: 'select2 trigger-submit', include_blank: true,
             data: {placeholder: 'Milestone'})
 
-        - if @project
-          .filter-item.inline.labels-filter
-            = select_tag('label_name', project_labels_options(@project),
-              class: 'select2 trigger-submit', include_blank: true,
-              data: {placeholder: 'Label'})
+        .filter-item.inline.labels-filter
+          = select_tag('label_name', projects_labels_options,
+            class: 'select2 trigger-submit', include_blank: true,
+            data: {placeholder: 'Label'})
 
         .pull-right
           = render 'shared/sort_dropdown'
-- 
GitLab