Commit 1b3fd278 authored by Jarka Košanová's avatar Jarka Košanová Committed by Kushal Pandya

Search epics by state in the finder

- add by_state filter to the epics finder
- support count by states
parent 9b1a3088
...@@ -128,7 +128,7 @@ class IssuableFinder ...@@ -128,7 +128,7 @@ class IssuableFinder
labels_count = 1 if use_cte_for_search? labels_count = 1 if use_cte_for_search?
finder.execute.reorder(nil).group(:state).count.each do |key, value| finder.execute.reorder(nil).group(:state).count.each do |key, value|
counts[Array(key).last.to_sym] += value / labels_count counts[count_key(key)] += value / labels_count
end end
counts[:all] = counts.values.sum counts[:all] = counts.values.sum
...@@ -297,6 +297,10 @@ class IssuableFinder ...@@ -297,6 +297,10 @@ class IssuableFinder
klass.all klass.all
end end
def count_key(value)
Array(value).last.to_sym
end
# rubocop: disable CodeReuse/ActiveRecord # rubocop: disable CodeReuse/ActiveRecord
def by_scope(items) def by_scope(items)
return items.none if current_user_related? && !current_user return items.none if current_user_related? && !current_user
......
...@@ -101,7 +101,7 @@ class Groups::EpicsController < Groups::ApplicationController ...@@ -101,7 +101,7 @@ class Groups::EpicsController < Groups::ApplicationController
# we need to override the default state which is opened for now because we don't have # we need to override the default state which is opened for now because we don't have
# states for epics and need all as default for navigation to work correctly (#4017) # states for epics and need all as default for navigation to work correctly (#4017)
def set_default_state def set_default_state
params[:state] = 'all' params[:state] = 'opened' if params[:state].blank?
end end
def authorize_create_epic! def authorize_create_epic!
......
...@@ -11,28 +11,12 @@ class EpicsFinder < IssuableFinder ...@@ -11,28 +11,12 @@ class EpicsFinder < IssuableFinder
items = by_search(items) items = by_search(items)
items = by_author(items) items = by_author(items)
items = by_timeframe(items) items = by_timeframe(items)
items = by_state(items)
items = by_label(items) items = by_label(items)
sort(items) sort(items)
end end
def row_count
count = execute.count
# When filtering by multiple labels, count returns a hash of
# records grouped by id - so we just have to get length of the Hash.
# Once we have state for epics, we can use default issuables row_count
# method.
count.is_a?(Hash) ? count.length : count
end
# we don't have states for epics for now this method (#4017)
def count_by_state
{
all: row_count
}
end
def group def group
return nil unless params[:group_id] return nil unless params[:group_id]
return @group if defined?(@group) return @group if defined?(@group)
...@@ -53,6 +37,10 @@ class EpicsFinder < IssuableFinder ...@@ -53,6 +37,10 @@ class EpicsFinder < IssuableFinder
private private
def count_key(value)
Epic.states.invert[Array(value).last].to_sym
end
# rubocop: disable CodeReuse/ActiveRecord # rubocop: disable CodeReuse/ActiveRecord
def groups_user_can_read_epics(groups) def groups_user_can_read_epics(groups)
groups = Gitlab::GroupPlansPreloader.new.preload(groups) groups = Gitlab::GroupPlansPreloader.new.preload(groups)
......
---
title: Add Open/Closed epics tabs in list view
merge_request: 7424
author:
type: added
...@@ -13,6 +13,15 @@ FactoryBot.define do ...@@ -13,6 +13,15 @@ FactoryBot.define do
due_date_is_fixed true due_date_is_fixed true
end end
trait :opened do
state :opened
end
trait :closed do
state :closed
closed_at { Time.now }
end
factory :labeled_epic do factory :labeled_epic do
transient do transient do
labels [] labels []
......
...@@ -5,10 +5,10 @@ describe EpicsFinder do ...@@ -5,10 +5,10 @@ describe EpicsFinder do
let(:search_user) { create(:user) } let(:search_user) { create(:user) }
let(:group) { create(:group, :private) } let(:group) { create(:group, :private) }
let(:another_group) { create(:group) } let(:another_group) { create(:group) }
let!(:epic1) { create(:epic, group: group, title: 'This is awesome epic', created_at: 1.week.ago) } let!(:epic1) { create(:epic, :opened, 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, end_date: 3.days.from_now) } let!(:epic2) { create(:epic, :opened, 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!(:epic3) { create(:epic, :closed, group: group, description: 'not so awesome', start_date: 5.days.ago, end_date: 3.days.ago) }
let!(:epic4) { create(:epic, group: another_group) } let!(:epic4) { create(:epic, :closed, group: another_group) }
describe '#execute' do describe '#execute' do
def epics(params = {}) def epics(params = {})
...@@ -106,6 +106,12 @@ describe EpicsFinder do ...@@ -106,6 +106,12 @@ describe EpicsFinder do
end end
end end
context 'by state' do
it 'returns all epics with given state' do
expect(epics(state: :closed)).to contain_exactly(epic3)
end
end
context 'when subgroups are supported', :nested_groups do context 'when subgroups are supported', :nested_groups do
let(:subgroup) { create(:group, :private, parent: group) } let(:subgroup) { create(:group, :private, parent: group) }
let(:subgroup2) { create(:group, :private, parent: subgroup) } let(:subgroup2) { create(:group, :private, parent: subgroup) }
...@@ -184,4 +190,17 @@ describe EpicsFinder do ...@@ -184,4 +190,17 @@ describe EpicsFinder do
expect(described_class.new(search_user, params).row_count).to eq(1) expect(described_class.new(search_user, params).row_count).to eq(1)
end end
end end
describe '#count_by_state' do
before do
group.add_developer(search_user)
stub_licensed_features(epics: true)
end
it 'returns correct counts' do
results = described_class.new(search_user, group_id: group.id).count_by_state
expect(results).to eq('opened' => 2, 'closed' => 1, 'all' => 3)
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