Commit f2a43ff5 authored by Felipe Artur's avatar Felipe Artur

Group boards CE backport

parent 5f88660a
module Boards
class ApplicationController < ::ApplicationController
respond_to :json
rescue_from ActiveRecord::RecordNotFound, with: :record_not_found
private
def board
@board ||= Board.find(params[:board_id])
end
def board_parent
@board_parent ||= board.parent
end
def record_not_found(exception)
render json: { error: exception.message }, status: :not_found
end
end
end
module Boards
class IssuesController < Boards::ApplicationController
include BoardsResponses
before_action :authorize_read_issue, only: [:index]
before_action :authorize_create_issue, only: [:create]
before_action :authorize_update_issue, only: [:update]
def index
issues = Boards::Issues::ListService.new(board_parent, current_user, filter_params).execute
issues = issues.page(params[:page]).per(params[:per] || 20)
make_sure_position_is_set(issues) unless Gitlab::Geo.secondary?
render json: {
issues: serialize_as_json(issues.preload(:project)),
size: issues.total_count
}
end
def create
service = Boards::Issues::CreateService.new(board_parent, project, current_user, issue_params)
issue = service.execute
if issue.valid?
render json: serialize_as_json(issue)
else
render json: issue.errors, status: :unprocessable_entity
end
end
def update
service = Boards::Issues::MoveService.new(board_parent, current_user, move_params)
if service.execute(issue)
head :ok
else
head :unprocessable_entity
end
end
private
def make_sure_position_is_set(issues)
issues.each do |issue|
issue.move_to_end && issue.save unless issue.relative_position
end
end
def issue
@issue ||= issues_finder.execute.find(params[:id])
end
def filter_params
params.merge(board_id: params[:board_id], id: params[:list_id])
.reject { |_, value| value.nil? }
end
def issues_finder
IssuesFinder.new(current_user, project_id: board_parent.id)
end
def project
@project ||= Project.find(issue_params[:project_id])
end
def move_params
params.permit(:board_id, :id, :from_list_id, :to_list_id, :move_before_id, :move_after_id)
end
def issue_params
params.require(:issue)
.permit(:title, :milestone_id, :project_id)
.merge(board_id: params[:board_id], list_id: params[:list_id], request: request)
end
def serialize_as_json(resource)
resource.as_json(
labels: true,
only: [:id, :iid, :project_id, :title, :confidential, :due_date, :relative_position],
include: {
project: { only: [:id, :path] },
assignees: { only: [:id, :name, :username], methods: [:avatar_url] },
milestone: { only: [:id, :title] }
},
user: current_user
)
end
end
end
module Boards
class ListsController < Boards::ApplicationController
include BoardsResponses
before_action :authorize_admin_list, only: [:create, :update, :destroy, :generate]
before_action :authorize_read_list, only: [:index]
def index
lists = Boards::Lists::ListService.new(board.parent, current_user).execute(board)
render json: serialize_as_json(lists)
end
def create
list = Boards::Lists::CreateService.new(board.parent, current_user, list_params).execute(board)
if list.valid?
render json: serialize_as_json(list)
else
render json: list.errors, status: :unprocessable_entity
end
end
def update
list = board.lists.movable.find(params[:id])
service = Boards::Lists::MoveService.new(board_parent, current_user, move_params)
if service.execute(list)
head :ok
else
head :unprocessable_entity
end
end
def destroy
list = board.lists.destroyable.find(params[:id])
service = Boards::Lists::DestroyService.new(board_parent, current_user)
if service.execute(list)
head :ok
else
head :unprocessable_entity
end
end
def generate
service = Boards::Lists::GenerateService.new(board_parent, current_user)
if service.execute(board)
render json: serialize_as_json(board.lists.movable)
else
head :unprocessable_entity
end
end
private
def list_params
params.require(:list).permit(:label_id)
end
def move_params
params.require(:list).permit(:position)
end
def serialize_as_json(resource)
resource.as_json(
only: [:id, :list_type, :position],
methods: [:title],
label: true
)
end
end
end
module Projects
module Boards
class ApplicationController < Projects::ApplicationController
respond_to :json
rescue_from ActiveRecord::RecordNotFound, with: :record_not_found
private
def record_not_found(exception)
render json: { error: exception.message }, status: :not_found
end
end
end
end
module Projects
module Boards
class IssuesController < Boards::ApplicationController
before_action :authorize_read_issue!, only: [:index]
before_action :authorize_create_issue!, only: [:create]
before_action :authorize_update_issue!, only: [:update]
def index
issues = ::Boards::Issues::ListService.new(project, current_user, filter_params).execute
issues = issues.page(params[:page]).per(params[:per] || 20)
make_sure_position_is_set(issues)
render json: {
issues: serialize_as_json(issues),
size: issues.total_count
}
end
def create
service = ::Boards::Issues::CreateService.new(project, current_user, issue_params)
issue = service.execute
if issue.valid?
render json: serialize_as_json(issue)
else
render json: issue.errors, status: :unprocessable_entity
end
end
def update
service = ::Boards::Issues::MoveService.new(project, current_user, move_params)
if service.execute(issue)
head :ok
else
head :unprocessable_entity
end
end
private
def make_sure_position_is_set(issues)
issues.each do |issue|
issue.move_to_end && issue.save unless issue.relative_position
end
end
def issue
@issue ||=
IssuesFinder.new(current_user, project_id: project.id)
.execute
.where(iid: params[:id])
.first!
end
def authorize_read_issue!
return render_403 unless can?(current_user, :read_issue, project)
end
def authorize_create_issue!
return render_403 unless can?(current_user, :admin_issue, project)
end
def authorize_update_issue!
return render_403 unless can?(current_user, :update_issue, issue)
end
def filter_params
params.merge(board_id: params[:board_id], id: params[:list_id])
.reject { |_, value| value.nil? }
end
def move_params
params.permit(:board_id, :id, :from_list_id, :to_list_id, :move_before_iid, :move_after_iid)
end
def issue_params
params.require(:issue).permit(:title).merge(board_id: params[:board_id], list_id: params[:list_id], request: request)
end
def serialize_as_json(resource)
resource.as_json(
labels: true,
only: [:id, :iid, :title, :confidential, :due_date, :relative_position],
include: {
assignees: { only: [:id, :name, :username], methods: [:avatar_url] },
milestone: { only: [:id, :title] }
},
user: current_user
)
end
end
end
end
module Projects
module Boards
class ListsController < Boards::ApplicationController
before_action :authorize_admin_list!, only: [:create, :update, :destroy, :generate]
before_action :authorize_read_list!, only: [:index]
def index
lists = ::Boards::Lists::ListService.new(project, current_user).execute(board)
render json: serialize_as_json(lists)
end
def create
list = ::Boards::Lists::CreateService.new(project, current_user, list_params).execute(board)
if list.valid?
render json: serialize_as_json(list)
else
render json: list.errors, status: :unprocessable_entity
end
end
def update
list = board.lists.movable.find(params[:id])
service = ::Boards::Lists::MoveService.new(project, current_user, move_params)
if service.execute(list)
head :ok
else
head :unprocessable_entity
end
end
def destroy
list = board.lists.destroyable.find(params[:id])
service = ::Boards::Lists::DestroyService.new(project, current_user)
if service.execute(list)
head :ok
else
head :unprocessable_entity
end
end
def generate
service = ::Boards::Lists::GenerateService.new(project, current_user)
if service.execute(board)
render json: serialize_as_json(board.lists.movable)
else
head :unprocessable_entity
end
end
private
def authorize_admin_list!
return render_403 unless can?(current_user, :admin_list, project)
end
def authorize_read_list!
return render_403 unless can?(current_user, :read_list, project)
end
def board
@board ||= project.boards.find(params[:board_id])
end
def list_params
params.require(:list).permit(:label_id)
end
def move_params
params.require(:list).permit(:position)
end
def serialize_as_json(resource)
resource.as_json(
only: [:id, :list_type, :position],
methods: [:title],
label: true
)
end
end
end
end
class Projects::BoardsController < Projects::ApplicationController class Projects::BoardsController < Projects::ApplicationController
include IssuableCollections include IssuableCollections
include BoardsResponses
before_action :authorize_read_board!, only: [:index, :show] before_action :authorize_read_board!, only: [:index, :show]
before_action :assign_endpoint_vars
def index def index
@boards = ::Boards::ListService.new(project, current_user).execute @boards = Boards::ListService.new(project, current_user).execute
respond_to do |format| respond_with_boards
format.html
format.json do
render json: serialize_as_json(@boards)
end
end
end end
def show def show
@board = project.boards.find(params[:id]) @board = project.boards.find(params[:id])
respond_to do |format| respond_with_board
format.html
format.json do
render json: serialize_as_json(@board)
end
end
end end
private private
def assign_endpoint_vars
@boards_endpoint = project_boards_url(project)
@bulk_issues_path = bulk_update_project_issues_path(project)
@namespace_path = project.namespace.path
@labels_endpoint = project_labels_path(project)
end
def authorize_read_board! def authorize_read_board!
return access_denied! unless can?(current_user, :read_board, project) return access_denied! unless can?(current_user, :read_board, project)
end end
......
module BoardsHelper module BoardsHelper
def board_data def board
board = @board || @boards.first @board ||= @board || @boards.first
end
def board_data
{ {
endpoint: project_boards_path(@project), boards_endpoint: @boards_endpoint,
lists_endpoint: board_lists_url(board),
board_id: board.id, board_id: board.id,
disabled: "#{!can?(current_user, :admin_list, @project)}", board_milestone_title: board&.milestone&.title,
issue_link_base: project_issues_path(@project), disabled: "#{!can?(current_user, :admin_list, current_board_parent)}",
issue_link_base: build_issue_link_base,
root_path: root_path, root_path: root_path,
bulk_update_path: bulk_update_project_issues_path(@project), bulk_update_path: @bulk_issues_path,
default_avatar: image_path(default_avatar) default_avatar: image_path(default_avatar)
} }
end end
def build_issue_link_base
project_issues_path(@project)
end
def current_board_json
board = @board || @boards.first
board.to_json(
only: [:id, :name, :milestone_id],
include: {
milestone: { only: [:title] }
}
)
end
def board_base_url
project_boards_path(@project)
end
def multiple_boards_available?
current_board_parent.multiple_issue_boards_available?(current_user)
end
def board_path(board)
@board_path ||= project_board_path(current_board_parent, board)
end
def current_board_parent
@current_board_parent ||= @project
end
def can_admin_issue?
can?(current_user, :admin_issue, current_board_parent)
end
def board_list_data
{
toggle: "dropdown",
list_labels_path: labels_filter_path(true),
labels: labels_filter_path(true),
labels_endpoint: @labels_endpoint,
namespace_path: @namespace_path,
project_path: @project&.try(:path)
}
end
def board_sidebar_user_data
dropdown_options = issue_assignees_dropdown_options
{
toggle: 'dropdown',
field_name: 'issue[assignee_ids][]',
first_user: current_user&.username,
current_user: 'true',
project_id: @project&.try(:id),
null_user: 'true',
multi_select: 'true',
'dropdown-header': dropdown_options[:data][:'dropdown-header'],
'max-select': dropdown_options[:data][:'max-select']
}
end
end end
...@@ -358,6 +358,14 @@ module IssuablesHelper ...@@ -358,6 +358,14 @@ module IssuablesHelper
end end
end end
def labels_path
if @project
project_labels_path(@project)
elsif @group
group_labels_path(@group)
end
end
def issuable_sidebar_options(issuable, can_edit_issuable) def issuable_sidebar_options(issuable, can_edit_issuable)
{ {
endpoint: "#{issuable_json_path(issuable)}?basic=true", endpoint: "#{issuable_json_path(issuable)}?basic=true",
......
...@@ -121,13 +121,14 @@ module LabelsHelper ...@@ -121,13 +121,14 @@ module LabelsHelper
end end
end end
def labels_filter_path def labels_filter_path(only_group_labels = false)
return group_labels_path(@group, :json) if @group
project = @target_project || @project project = @target_project || @project
if project if project
project_labels_path(project, :json) project_labels_path(project, :json)
elsif @group
options = { only_group_labels: only_group_labels } if only_group_labels
group_labels_path(@group, :json, options)
else else
dashboard_labels_path(:json) dashboard_labels_path(:json)
end end
......
...@@ -127,7 +127,8 @@ module SearchHelper ...@@ -127,7 +127,8 @@ module SearchHelper
end end
def search_filter_input_options(type) def search_filter_input_options(type)
opts = { opts =
{
id: "filtered-search-#{type}", id: "filtered-search-#{type}",
placeholder: 'Search or filter results...', placeholder: 'Search or filter results...',
data: { data: {
...@@ -140,6 +141,7 @@ module SearchHelper ...@@ -140,6 +141,7 @@ module SearchHelper
opts[:data]['base-endpoint'] = project_path(@project) opts[:data]['base-endpoint'] = project_path(@project)
else else
# Group context # Group context
opts[:data]['group-id'] = @group.id
opts[:data]['base-endpoint'] = group_canonical_path(@group) opts[:data]['base-endpoint'] = group_canonical_path(@group)
end end
......
...@@ -3,7 +3,11 @@ class Board < ActiveRecord::Base ...@@ -3,7 +3,11 @@ class Board < ActiveRecord::Base
has_many :lists, -> { order(:list_type, :position) }, dependent: :delete_all # rubocop:disable Cop/ActiveRecordDependent has_many :lists, -> { order(:list_type, :position) }, dependent: :delete_all # rubocop:disable Cop/ActiveRecordDependent
validates :project, presence: true validates :project, presence: true, if: :project_needed?
def project_needed?
true
end
def backlog_list def backlog_list
lists.merge(List.backlog).take lists.merge(List.backlog).take
......
...@@ -10,8 +10,12 @@ module RelativePositioning ...@@ -10,8 +10,12 @@ module RelativePositioning
after_save :save_positionable_neighbours after_save :save_positionable_neighbours
end end
def project_ids
[project.id]
end
def max_relative_position def max_relative_position
self.class.in_projects(project.id).maximum(:relative_position) self.class.in_projects(project_ids).maximum(:relative_position)
end end
def prev_relative_position def prev_relative_position
...@@ -19,7 +23,7 @@ module RelativePositioning ...@@ -19,7 +23,7 @@ module RelativePositioning
if self.relative_position if self.relative_position
prev_pos = self.class prev_pos = self.class
.in_projects(project.id) .in_projects(project_ids)
.where('relative_position < ?', self.relative_position) .where('relative_position < ?', self.relative_position)
.maximum(:relative_position) .maximum(:relative_position)
end end
...@@ -32,7 +36,7 @@ module RelativePositioning ...@@ -32,7 +36,7 @@ module RelativePositioning
if self.relative_position if self.relative_position
next_pos = self.class next_pos = self.class
.in_projects(project.id) .in_projects(project_ids)
.where('relative_position > ?', self.relative_position) .where('relative_position > ?', self.relative_position)
.minimum(:relative_position) .minimum(:relative_position)
end end
...@@ -59,7 +63,7 @@ module RelativePositioning ...@@ -59,7 +63,7 @@ module RelativePositioning
pos_after = before.next_relative_position pos_after = before.next_relative_position
if before.shift_after? if before.shift_after?
issue_to_move = self.class.in_projects(project.id).find_by!(relative_position: pos_after) issue_to_move = self.class.in_projects(project_ids).find_by!(relative_position: pos_after)
issue_to_move.move_after issue_to_move.move_after
@positionable_neighbours = [issue_to_move] @positionable_neighbours = [issue_to_move]
...@@ -74,7 +78,7 @@ module RelativePositioning ...@@ -74,7 +78,7 @@ module RelativePositioning
pos_before = after.prev_relative_position pos_before = after.prev_relative_position
if after.shift_before? if after.shift_before?
issue_to_move = self.class.in_projects(project.id).find_by!(relative_position: pos_before) issue_to_move = self.class.in_projects(project_ids).find_by!(relative_position: pos_before)
issue_to_move.move_before issue_to_move.move_before
@positionable_neighbours = [issue_to_move] @positionable_neighbours = [issue_to_move]
......
...@@ -34,7 +34,8 @@ class Label < ActiveRecord::Base ...@@ -34,7 +34,8 @@ class Label < ActiveRecord::Base
scope :templates, -> { where(template: true) } scope :templates, -> { where(template: true) }
scope :with_title, ->(title) { where(title: title) } scope :with_title, ->(title) { where(title: title) }
scope :on_project_boards, ->(project_id) { joins(lists: :board).merge(List.movable).where(boards: { project_id: project_id }) } scope :with_lists_and_board, -> { joins(lists: :board).merge(List.movable) }
scope :on_project_boards, ->(project_id) { with_lists_and_board.where(boards: { project_id: project_id }) }
def self.prioritized(project) def self.prioritized(project)
joins(:priorities) joins(:priorities)
......
...@@ -1469,6 +1469,14 @@ class Project < ActiveRecord::Base ...@@ -1469,6 +1469,14 @@ class Project < ActiveRecord::Base
end end
end end
def multiple_issue_boards_available?(user)
feature_available?(:multiple_issue_boards, user)
end
def issue_board_milestone_available?(user = nil)
feature_available?(:issue_board_milestone, user)
end
def full_path_was def full_path_was
File.join(namespace.full_path, previous_changes['path'].first) File.join(namespace.full_path, previous_changes['path'].first)
end end
......
module Boards
class BaseService < ::BaseService
# Parent can either a group or a project
attr_accessor :parent, :current_user, :params
def initialize(parent, user, params = {})
@parent, @current_user, @params = parent, user, params.dup
end
end
end
module Boards module Boards
class CreateService < BaseService class CreateService < Boards::BaseService
def execute def execute
create_board! if can_create_board? create_board! if can_create_board?
end end
...@@ -7,11 +7,11 @@ module Boards ...@@ -7,11 +7,11 @@ module Boards
private private
def can_create_board? def can_create_board?
project.boards.size == 0 parent.boards.size == 0
end end
def create_board! def create_board!
board = project.boards.create(params) board = parent.boards.create(params)
if board.persisted? if board.persisted?
board.lists.create(list_type: :backlog) board.lists.create(list_type: :backlog)
......
module Boards module Boards
module Issues module Issues
class CreateService < BaseService class CreateService < Boards::BaseService
attr_accessor :project
def initialize(parent, project, user, params = {})
@project = project
super(parent, user, params)
end
def execute def execute
create_issue(params.merge(label_ids: [list.label_id])) create_issue(params.merge(label_ids: [list.label_id]))
end end
...@@ -8,7 +16,7 @@ module Boards ...@@ -8,7 +16,7 @@ module Boards
private private
def board def board
@board ||= project.boards.find(params.delete(:board_id)) @board ||= parent.boards.find(params.delete(:board_id))
end end
def list def list
......
module Boards module Boards
module Issues module Issues
class ListService < BaseService class ListService < Boards::BaseService
def execute def execute
issues = IssuesFinder.new(current_user, filter_params).execute issues = IssuesFinder.new(current_user, filter_params).execute
issues = without_board_labels(issues) unless movable_list? || closed_list? issues = without_board_labels(issues) unless movable_list? || closed_list?
...@@ -11,7 +11,7 @@ module Boards ...@@ -11,7 +11,7 @@ module Boards
private private
def board def board
@board ||= project.boards.find(params[:board_id]) @board ||= parent.boards.find(params[:board_id])
end end
def list def list
...@@ -33,13 +33,13 @@ module Boards ...@@ -33,13 +33,13 @@ module Boards
end end
def filter_params def filter_params
set_project set_parent
set_state set_state
params params
end end
def set_project def set_parent
params[:project_id] = project.id params[:project_id] = project.id
end end
......
module Boards module Boards
module Issues module Issues
class MoveService < BaseService class MoveService < Boards::BaseService
def execute(issue) def execute(issue)
return false unless can?(current_user, :update_issue, issue) return false unless can?(current_user, :update_issue, issue)
return false if issue_params.empty? return false if issue_params.empty?
update_service.execute(issue) update(issue)
end end
private private
def board def board
@board ||= project.boards.find(params[:board_id]) @board ||= parent.boards.find(params[:board_id])
end end
def move_between_lists? def move_between_lists?
...@@ -27,8 +27,8 @@ module Boards ...@@ -27,8 +27,8 @@ module Boards
@moving_to_list ||= board.lists.find_by(id: params[:to_list_id]) @moving_to_list ||= board.lists.find_by(id: params[:to_list_id])
end end
def update_service def update(issue)
::Issues::UpdateService.new(project, current_user, issue_params) ::Issues::UpdateService.new(issue.project, current_user, issue_params).execute(issue)
end end
def issue_params def issue_params
...@@ -42,7 +42,7 @@ module Boards ...@@ -42,7 +42,7 @@ module Boards
) )
end end
attrs[:move_between_iids] = move_between_iids if move_between_iids attrs[:move_between_ids] = move_between_ids if move_between_ids
attrs attrs
end end
...@@ -61,16 +61,16 @@ module Boards ...@@ -61,16 +61,16 @@ module Boards
if moving_to_list.movable? if moving_to_list.movable?
moving_from_list.label_id moving_from_list.label_id
else else
Label.on_project_boards(project.id).pluck(:label_id) Label.on_project_boards(parent.id).pluck(:label_id)
end end
Array(label_ids).compact Array(label_ids).compact
end end
def move_between_iids def move_between_ids
return unless params[:move_after_iid] || params[:move_before_iid] return unless params[:move_after_id] || params[:move_before_id]
[params[:move_after_iid], params[:move_before_iid]] [params[:move_after_id], params[:move_before_id]]
end end
end end
end end
......
module Boards module Boards
class ListService < BaseService class ListService < Boards::BaseService
def execute def execute
create_board! if project.boards.empty? create_board! if parent.boards.empty?
project.boards parent.boards
end end
private private
def create_board! def create_board!
Boards::CreateService.new(project, current_user).execute Boards::CreateService.new(parent, current_user).execute
end end
end end
end end
...@@ -3,17 +3,16 @@ module Boards ...@@ -3,17 +3,16 @@ module Boards
class CreateService < BaseService class CreateService < BaseService
def execute(board) def execute(board)
List.transaction do List.transaction do
label = available_labels.find(params[:label_id]) label = available_labels_for(board).find(params[:label_id])
position = next_position(board) position = next_position(board)
create_list(board, label, position) create_list(board, label, position)
end end
end end
private private
def available_labels def available_labels_for(board)
LabelsFinder.new(current_user, project_id: project.id).execute LabelsFinder.new(current_user, project_id: parent.id).execute
end end
def next_position(board) def next_position(board)
......
...@@ -15,11 +15,11 @@ module Boards ...@@ -15,11 +15,11 @@ module Boards
def create_list(board, params) def create_list(board, params)
label = find_or_create_label(params) label = find_or_create_label(params)
Lists::CreateService.new(project, current_user, label_id: label.id).execute(board) Lists::CreateService.new(parent, current_user, label_id: label.id).execute(board)
end end
def find_or_create_label(params) def find_or_create_label(params)
::Labels::FindOrCreateService.new(current_user, project, params).execute ::Labels::FindOrCreateService.new(current_user, parent, params).execute
end end
def label_params def label_params
......
...@@ -3,7 +3,7 @@ module Issues ...@@ -3,7 +3,7 @@ module Issues
include SpamCheckService include SpamCheckService
def execute(issue) def execute(issue)
handle_move_between_iids(issue) handle_move_between_ids(issue)
filter_spam_check_params filter_spam_check_params
change_issue_duplicate(issue) change_issue_duplicate(issue)
update(issue) update(issue)
...@@ -55,12 +55,12 @@ module Issues ...@@ -55,12 +55,12 @@ module Issues
end end
def handle_move_between_iids(issue) def handle_move_between_iids(issue)
return unless params[:move_between_iids] return unless params[:move_between_ids]
after_iid, before_iid = params.delete(:move_between_iids) after_id, before_id = params.delete(:move_between_ids)
issue_before = get_issue_if_allowed(issue.project, before_iid) if before_iid issue_before = get_issue_if_allowed(issue.project, before_id) if before_id
issue_after = get_issue_if_allowed(issue.project, after_iid) if after_iid issue_after = get_issue_if_allowed(issue.project, after_id) if after_id
issue.move_between(issue_before, issue_after) issue.move_between(issue_before, issue_after)
end end
...@@ -76,8 +76,8 @@ module Issues ...@@ -76,8 +76,8 @@ module Issues
private private
def get_issue_if_allowed(project, iid) def get_issue_if_allowed(project, id)
issue = project.issues.find_by(iid: iid) issue = project.issues.find(id)
issue if can?(current_user, :update_issue, issue) issue if can?(current_user, :update_issue, issue)
end end
......
...@@ -73,6 +73,19 @@ Rails.application.routes.draw do ...@@ -73,6 +73,19 @@ Rails.application.routes.draw do
# Notification settings # Notification settings
resources :notification_settings, only: [:create, :update] resources :notification_settings, only: [:create, :update]
# Boards resources shared between group and projects
resources :boards do
resources :lists, module: :boards, only: [:index, :create, :update, :destroy] do
collection do
post :generate
end
resources :issues, only: [:index, :create, :update]
end
resources :issues, module: :boards, only: [:index, :update]
end
draw :import draw :import
draw :uploads draw :uploads
draw :explore draw :explore
......
...@@ -341,19 +341,7 @@ constraints(ProjectUrlConstrainer.new) do ...@@ -341,19 +341,7 @@ constraints(ProjectUrlConstrainer.new) do
get 'noteable/:target_type/:target_id/notes' => 'notes#index', as: 'noteable_notes' get 'noteable/:target_type/:target_id/notes' => 'notes#index', as: 'noteable_notes'
resources :boards, only: [:index, :show] do resources :boards, only: [:index, :show, :create, :update, :destroy]
scope module: :boards do
resources :issues, only: [:index, :update]
resources :lists, only: [:index, :create, :update, :destroy] do
collection do
post :generate
end
resources :issues, only: [:index, :create]
end
end
end
resources :todos, only: [:create] resources :todos, only: [:create]
......
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