diff options
author | Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com> | 2016-10-06 14:40:03 +0300 |
---|---|---|
committer | Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com> | 2016-10-06 14:40:03 +0300 |
commit | ab18d6b7a9d7e6a9d1f04a7e2c3279fa5d136d89 (patch) | |
tree | 0710c242598fb9c9634d3b187a884ce9a5652dde /lib | |
parent | 9cc700315ac4d38b5a752ea4eb481e37cb547379 (diff) | |
parent | 41d70ea300efb73a05f4753ddd3e0c3730e96e0a (diff) |
Merge branch 'issue-board-api-support' into 'master'
Issue Board API support
## What does this MR do?
Adds support for Issue Board in the API.
## Are there points in the code the reviewer needs to double check?
~~Double check whether the Issue Board list movement fix is needed.~~
*Moved to a separate issue.* [#22890](https://gitlab.com/gitlab-org/gitlab-ce/issues/22890)
## Why was this MR needed?
Currently the API offers partial support to a project's Issue Board indirectly through Labels.
This MR adds support for listing, creating, moving and removing board lists.
## Does this MR meet the acceptance criteria?
- [X] [CHANGELOG](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CHANGELOG) entry added
- [X] [Documentation created/updated](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/development/doc_styleguide.md)
- [X] API support added
- Tests
- [X] Added for this feature/bug
- [X] All builds are passing
- [X] Conform by the [merge request performance guides](http://docs.gitlab.com/ce/development/merge_request_performance_guidelines.html)
- [X] Conform by the [style guides](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md#style-guides)
- [X] Branch has no merge conflicts with `master` (if you do - rebase it please)
- [X] [Squashed related commits together](https://git-scm.com/book/en/Git-Tools-Rewriting-History#Squashing-Commits)
## What are the relevant issue numbers?
[#22195](https://gitlab.com/gitlab-org/gitlab-ce/issues/22195)
See merge request !6646
Diffstat (limited to 'lib')
-rw-r--r-- | lib/api/api.rb | 1 | ||||
-rw-r--r-- | lib/api/boards.rb | 115 | ||||
-rw-r--r-- | lib/api/entities.rb | 18 |
3 files changed, 133 insertions, 1 deletions
diff --git a/lib/api/api.rb b/lib/api/api.rb index cb47ec8f33f..0bbf73a1b63 100644 --- a/lib/api/api.rb +++ b/lib/api/api.rb @@ -43,6 +43,7 @@ module API mount ::API::Groups mount ::API::Internal mount ::API::Issues + mount ::API::Boards mount ::API::Keys mount ::API::Labels mount ::API::LicenseTemplates diff --git a/lib/api/boards.rb b/lib/api/boards.rb new file mode 100644 index 00000000000..4d5d144a02e --- /dev/null +++ b/lib/api/boards.rb @@ -0,0 +1,115 @@ +module API + # Boards API + class Boards < Grape::API + before { authenticate! } + + resource :projects do + # Get the project board + get ':id/boards' do + authorize!(:read_board, user_project) + present [user_project.board], with: Entities::Board + end + + segment ':id/boards/:board_id' do + helpers do + def project_board + board = user_project.board + if params[:board_id].to_i == board.id + board + else + not_found!('Board') + end + end + + def board_lists + project_board.lists.destroyable + end + end + + # Get the lists of a project board + # Does not include `backlog` and `done` lists + get '/lists' do + authorize!(:read_board, user_project) + present board_lists, with: Entities::List + end + + # Get a list of a project board + get '/lists/:list_id' do + authorize!(:read_board, user_project) + present board_lists.find(params[:list_id]), with: Entities::List + end + + # Create a new board list + # + # Parameters: + # id (required) - The ID of a project + # label_id (required) - The ID of an existing label + # Example Request: + # POST /projects/:id/boards/:board_id/lists + post '/lists' do + required_attributes! [:label_id] + + unless user_project.labels.exists?(params[:label_id]) + render_api_error!({ error: "Label not found!" }, 400) + end + + authorize!(:admin_list, user_project) + + list = ::Boards::Lists::CreateService.new(user_project, current_user, + { label_id: params[:label_id] }).execute + + if list.valid? + present list, with: Entities::List + else + render_validation_error!(list) + end + end + + # Moves a board list to a new position + # + # Parameters: + # id (required) - The ID of a project + # board_id (required) - The ID of a board + # position (required) - The position of the list + # Example Request: + # PUT /projects/:id/boards/:board_id/lists/:list_id + put '/lists/:list_id' do + list = project_board.lists.movable.find(params[:list_id]) + + authorize!(:admin_list, user_project) + + moved = ::Boards::Lists::MoveService.new(user_project, current_user, + { position: params[:position].to_i }).execute(list) + + if moved + present list, with: Entities::List + else + render_api_error!({ error: "List could not be moved!" }, 400) + end + end + + # Delete a board list + # + # Parameters: + # id (required) - The ID of a project + # board_id (required) - The ID of a board + # list_id (required) - The ID of a board list + # Example Request: + # DELETE /projects/:id/boards/:board_id/lists/:list_id + delete "/lists/:list_id" do + list = board_lists.find_by(id: params[:list_id]) + + authorize!(:admin_list, user_project) + + if list + destroyed_list = ::Boards::Lists::DestroyService.new( + user_project, current_user).execute(list) + present destroyed_list, with: Entities::List + else + not_found!('List') + end + end + end + end + end +end diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 04437322ec1..feaa0c213bf 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -432,8 +432,11 @@ module API end end - class Label < Grape::Entity + class LabelBasic < Grape::Entity expose :name, :color, :description + end + + class Label < LabelBasic expose :open_issues_count, :closed_issues_count, :open_merge_requests_count expose :subscribed do |label, options| @@ -441,6 +444,19 @@ module API end end + class List < Grape::Entity + expose :id + expose :label, using: Entities::LabelBasic + expose :position + end + + class Board < Grape::Entity + expose :id + expose :lists, using: Entities::List do |board| + board.lists.destroyable + end + end + class Compare < Grape::Entity expose :commit, using: Entities::RepoCommit do |compare, options| Commit.decorate(compare.commits, nil).last |