Commit 2240c5e4 authored by Felipe Artur's avatar Felipe Artur

Allow to hide boards closed and backlog lists

Persist options to hide boards  backlog and closed lists
on database.
parent 609d185d
---
title: Add hide_backlog_list and hide_closed_list attributes to boards table
merge_request: 38303
author:
type: added
# frozen_string_literal: true
class AddHideListsToBoards < ActiveRecord::Migration[6.0]
DOWNTIME = false
def change
add_column :boards, :hide_backlog_list, :boolean, default: false, null: false
add_column :boards, :hide_closed_list, :boolean, default: false, null: false
end
end
4ef0dfb9cdeccd57a3c11d1db0b57448746237d4a1fe001340575c996a6c3c68
\ No newline at end of file
...@@ -9660,7 +9660,9 @@ CREATE TABLE public.boards ( ...@@ -9660,7 +9660,9 @@ CREATE TABLE public.boards (
name character varying DEFAULT 'Development'::character varying NOT NULL, name character varying DEFAULT 'Development'::character varying NOT NULL,
milestone_id integer, milestone_id integer,
group_id integer, group_id integer,
weight integer weight integer,
hide_backlog_list boolean DEFAULT false NOT NULL,
hide_closed_list boolean DEFAULT false NOT NULL
); );
CREATE SEQUENCE public.boards_id_seq CREATE SEQUENCE public.boards_id_seq
......
...@@ -37,6 +37,8 @@ module EE ...@@ -37,6 +37,8 @@ module EE
base.validates :list_type, base.validates :list_type,
exclusion: { in: %w[milestone], message: _('Milestone lists not available with your current license') }, exclusion: { in: %w[milestone], message: _('Milestone lists not available with your current license') },
unless: -> { board&.resource_parent&.feature_available?(:board_milestone_lists) } unless: -> { board&.resource_parent&.feature_available?(:board_milestone_lists) }
base.scope :without_types, ->(list_types) { where.not(list_type: list_types) }
end end
def assignee=(user) def assignee=(user)
......
...@@ -12,24 +12,32 @@ module EE ...@@ -12,24 +12,32 @@ module EE
override :execute override :execute
def execute(board, create_default_lists: true) def execute(board, create_default_lists: true)
not_available_lists = list_type_features_availability(board) list_types = unavailable_list_types_for(board)
.select { |_, available| !available }
if not_available_lists.any? super.without_types(list_types)
super.where.not(list_type: not_available_lists.keys) # rubocop: disable CodeReuse/ActiveRecord
else
super
end
end end
private private
def list_type_features_availability(board) def unavailable_list_types_for(board)
(hidden_lists_for(board) + unlicensed_lists_for(board)).uniq
end
def hidden_lists_for(board)
hidden = []
hidden << ::List.list_types[:backlog] if board.hide_backlog_list
hidden << ::List.list_types[:closed] if board.hide_closed_list
hidden
end
def unlicensed_lists_for(board)
parent = board.resource_parent parent = board.resource_parent
LICENSED_LIST_TYPES.each_with_object({}) do |list_type, hash| LICENSED_LIST_TYPES.each_with_object([]) do |list_type, lists|
list_type_key = ::List.list_types[list_type] list_type_key = ::List.list_types[list_type]
hash[list_type_key] = parent&.feature_available?(:"board_#{list_type}_lists") lists << list_type_key unless parent&.feature_available?(:"board_#{list_type}_lists")
end end
end end
end end
......
...@@ -12,6 +12,8 @@ module EE ...@@ -12,6 +12,8 @@ module EE
params.delete(:assignee_id) params.delete(:assignee_id)
params.delete(:label_ids) params.delete(:label_ids)
params.delete(:weight) params.delete(:weight)
params.delete(:hide_backlog_list)
params.delete(:hide_closed_list)
end end
set_assignee set_assignee
......
...@@ -35,6 +35,19 @@ RSpec.describe List do ...@@ -35,6 +35,19 @@ RSpec.describe List do
end end
end end
describe '.without_types' do
it 'exclude lists of given types' do
board = create(:list, list_type: :label).board
# closed list is created by default
backlog_list = create(:list, list_type: :backlog, board: board)
exclude_type = [described_class.list_types[:label], described_class.list_types[:closed]]
lists = described_class.without_types(exclude_type)
expect(lists.where(board: board)).to match_array([backlog_list])
end
end
context 'when it is a milestone type' do context 'when it is a milestone type' do
let(:milestone) { build(:milestone, title: 'awesome-release') } let(:milestone) { build(:milestone, title: 'awesome-release') }
......
...@@ -34,28 +34,24 @@ RSpec.describe Boards::UpdateService, services: true do ...@@ -34,28 +34,24 @@ RSpec.describe Boards::UpdateService, services: true do
milestone = create(:milestone, group: group) milestone = create(:milestone, group: group)
label = create(:group_label, group: board.group) label = create(:group_label, group: board.group)
user = create(:user) user = create(:user)
params = { milestone_id: milestone.id, assignee_id: assignee.id, label_ids: [label.id], hide_backlog_list: true, hide_closed_list: true }
service = described_class.new(group, user, params)
service = described_class.new(group, user,
milestone_id: milestone.id,
assignee_id: assignee.id,
label_ids: [label.id])
service.execute(board) service.execute(board)
expect(board.reload).to have_attributes(milestone: milestone, expected_attributes = { milestone: milestone, assignee: assignee, labels: [label], hide_backlog_list: true, hide_closed_list: true }
assignee: assignee, expect(board.reload).to have_attributes(expected_attributes)
labels: [label])
end end
it 'filters unpermitted params when scoped issue board is not enabled' do it 'filters unpermitted params when scoped issue board is not enabled' do
stub_licensed_features(scoped_issue_board: false) stub_licensed_features(scoped_issue_board: false)
params = { milestone_id: double, assignee_id: double, label_ids: double, weight: double } params = { milestone_id: double, assignee_id: double, label_ids: double, weight: double, hide_backlog_list: true, hide_closed_list: true }
service = described_class.new(project, double, params) service = described_class.new(project, double, params)
service.execute(board) service.execute(board)
expect(board.reload).to have_attributes(milestone: nil, expected_attributes = { milestone: nil, assignee: nil, labels: [], hide_backlog_list: false, hide_closed_list: false }
assignee: nil, expect(board.reload).to have_attributes(expected_attributes)
labels: [])
end end
it_behaves_like 'setting a milestone scope' do it_behaves_like 'setting a milestone scope' do
......
...@@ -51,6 +51,26 @@ RSpec.describe Boards::Lists::ListService do ...@@ -51,6 +51,26 @@ RSpec.describe Boards::Lists::ListService do
end end
end end
shared_examples 'hidden lists' do
let!(:list) { create(:list, board: board, label: label) }
context 'when hide_backlog_list is true' do
it 'hides backlog list' do
board.update(hide_backlog_list: true)
expect(service.execute(board)).to match_array([board.closed_list, list])
end
end
context 'when hide_closed_list is true' do
it 'hides closed list' do
board.update(hide_closed_list: true)
expect(service.execute(board)).to match_array([board.backlog_list, list])
end
end
end
context 'when board parent is a project' do context 'when board parent is a project' do
let(:user) { create(:user) } let(:user) { create(:user) }
let(:project) { create(:project) } let(:project) { create(:project) }
...@@ -60,6 +80,7 @@ RSpec.describe Boards::Lists::ListService do ...@@ -60,6 +80,7 @@ RSpec.describe Boards::Lists::ListService do
it_behaves_like 'list service for board with assignee lists' it_behaves_like 'list service for board with assignee lists'
it_behaves_like 'list service for board with milestone lists' it_behaves_like 'list service for board with milestone lists'
it_behaves_like 'hidden lists'
end end
context 'when board parent is a group' do context 'when board parent is a group' do
...@@ -71,6 +92,7 @@ RSpec.describe Boards::Lists::ListService do ...@@ -71,6 +92,7 @@ RSpec.describe Boards::Lists::ListService do
it_behaves_like 'list service for board with assignee lists' it_behaves_like 'list service for board with assignee lists'
it_behaves_like 'list service for board with milestone lists' it_behaves_like 'list service for board with milestone lists'
it_behaves_like 'hidden lists'
end end
end end
end end
...@@ -737,6 +737,8 @@ Board: ...@@ -737,6 +737,8 @@ Board:
- milestone_id - milestone_id
- weight - weight
- name - name
- hide_backlog_list
- hide_closed_list
List: List:
- id - id
- board_id - board_id
......
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