summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAlexandru Croitor <acroitor@gitlab.com>2019-04-08 14:17:22 +0300
committerAlexandru Croitor <acroitor@gitlab.com>2019-05-15 10:15:16 +0300
commit5ec28dc387fb4adc3c5b65ac47819a8663186954 (patch)
tree4e40a2bf57265d1613ab207e18ab45ee2c4195a5 /lib
parent6bf5af2acd5e046d4235dee6473c214e91d86379 (diff)
downloadgitlab-ce-5ec28dc387fb4adc3c5b65ac47819a8663186954.tar.gz
Changes to issues api
When issues_controller endpoint was used for search, the parameters passed to the controller were slightly different then the ones passed to API. Because the searchbar UI is reused in different places and builds the parameters passed to request in same way we need to account for old parameter names. Add issues_statistics api endpoints Adds issue_statistics api endpoints for issue lists and returns counts of issues for all, closed and opened states. Expose more label attributes based on a param When requesting issues list through API expose more attributes for labels, like color, description if with_labels_data param is being passed, avoiding this way to change response schema for users that already use API. https://gitlab.com/gitlab-org/gitlab-ce/issues/57402
Diffstat (limited to 'lib')
-rw-r--r--lib/api/entities.rb10
-rw-r--r--lib/api/helpers/issues_helpers.rb37
-rw-r--r--lib/api/issues.rb78
3 files changed, 97 insertions, 28 deletions
diff --git a/lib/api/entities.rb b/lib/api/entities.rb
index 296688ba25b..a57c7e9f851 100644
--- a/lib/api/entities.rb
+++ b/lib/api/entities.rb
@@ -542,9 +542,13 @@ module API
class IssueBasic < ProjectEntity
expose :closed_at
expose :closed_by, using: Entities::UserBasic
- expose :labels do |issue|
+ expose :labels do |issue, options|
# Avoids an N+1 query since labels are preloaded
- issue.labels.map(&:title).sort
+ if options[:with_labels_data]
+ ::API::Entities::LabelBasic.represent(issue.labels.sort_by(&:title))
+ else
+ issue.labels.map(&:title).sort
+ end
end
expose :milestone, using: Entities::Milestone
expose :assignees, :author, using: Entities::UserBasic
@@ -560,6 +564,8 @@ module API
expose :due_date
expose :confidential
expose :discussion_locked
+ expose(:has_tasks) {|issue, _| !issue.task_list_items.empty? }
+ expose :task_status, if: -> (issue, _) { !issue.task_list_items.empty? }
expose :web_url do |issue|
Gitlab::UrlBuilder.build(issue)
diff --git a/lib/api/helpers/issues_helpers.rb b/lib/api/helpers/issues_helpers.rb
index f6762910b0c..00aaf5243b7 100644
--- a/lib/api/helpers/issues_helpers.rb
+++ b/lib/api/helpers/issues_helpers.rb
@@ -18,6 +18,43 @@ module API
:title
]
end
+
+ def issue_finder(args = {})
+ args = declared_params.merge(args)
+
+ args.delete(:id)
+ args[:milestone_title] ||= args.delete(:milestone)
+ args[:milestone_title] ||= args.delete(:milestone_title)
+ args[:label_name] ||= args.delete(:labels)
+ args[:scope] = args[:scope].underscore if args[:scope]
+
+ IssuesFinder.new(current_user, args)
+ end
+
+ def find_issues(args = {})
+ # rubocop: disable CodeReuse/ActiveRecord
+ finder = issue_finder(args)
+ issues = finder.execute.with_api_entity_associations
+ order_by = declared_params[:sort].present? && %w(asc desc).include?(declared_params[:sort].downcase)
+ issues = issues.reorder(order_options_with_tie_breaker) if order_by
+ issues
+ # rubocop: enable CodeReuse/ActiveRecord
+ end
+
+ def issues_statistics(args = {})
+ finder = issue_finder(args)
+ counter = Gitlab::IssuablesCountForState.new(finder)
+
+ {
+ statistics: {
+ counts: {
+ all: counter[:all],
+ closed: counter[:closed],
+ opened: counter[:opened]
+ }
+ }
+ }
+ end
end
end
end
diff --git a/lib/api/issues.rb b/lib/api/issues.rb
index d0a93b77951..67da1c46480 100644
--- a/lib/api/issues.rb
+++ b/lib/api/issues.rb
@@ -3,27 +3,12 @@
module API
class Issues < Grape::API
include PaginationParams
+ helpers Helpers::IssuesHelpers
+ helpers ::Gitlab::IssuableMetadata
before { authenticate_non_get! }
- helpers ::Gitlab::IssuableMetadata
-
helpers do
- # rubocop: disable CodeReuse/ActiveRecord
- def find_issues(args = {})
- args = declared_params.merge(args)
-
- args.delete(:id)
- args[:milestone_title] = args.delete(:milestone)
- args[:label_name] = args.delete(:labels)
- args[:scope] = args[:scope].underscore if args[:scope]
-
- issues = IssuesFinder.new(current_user, args).execute
- .with_api_entity_associations
- issues.reorder(order_options_with_tie_breaker)
- end
- # rubocop: enable CodeReuse/ActiveRecord
-
if Gitlab.ee?
params :issues_params_ee do
optional :weight, types: [Integer, String], integer_none_any: true, desc: 'The weight of the issue'
@@ -35,13 +20,14 @@ module API
end
params :issues_params do
- optional :labels, type: Array[String], coerce_with: Validations::Types::LabelsList.coerce, desc: 'Comma-separated list of label names'
+ optional :labels, :label_name, type: Array[String], coerce_with: Validations::Types::LabelsList.coerce, desc: 'Comma-separated list of label names'
+ optional :with_labels_data, type: Boolean, desc: 'Return more label data than just lable title', default: false
optional :milestone, type: String, desc: 'Milestone title'
optional :order_by, type: String, values: %w[created_at updated_at], default: 'created_at',
desc: 'Return issues ordered by `created_at` or `updated_at` fields.'
- optional :sort, type: String, values: %w[asc desc], default: 'desc',
+ optional :sort, type: String, default: 'desc',
desc: 'Return issues sorted in `asc` or `desc` order.'
- optional :milestone, type: String, desc: 'Return issues for a specific milestone'
+ optional :milestone, :milestone_title, type: String, desc: 'Return issues for a specific milestone'
optional :iids, type: Array[Integer], desc: 'The IID array of issues'
optional :search, type: String, desc: 'Search issues for text present in the title, description, or any combination of these'
optional :in, type: String, desc: '`title`, `description`, or a string joining them with comma'
@@ -50,12 +36,17 @@ module API
optional :updated_after, type: DateTime, desc: 'Return issues updated after the specified time'
optional :updated_before, type: DateTime, desc: 'Return issues updated before the specified time'
optional :author_id, type: Integer, desc: 'Return issues which are authored by the user with the given ID'
+ optional :author_username, type: String, desc: 'Return issues which are authored by the user with the given username'
optional :assignee_id, types: [Integer, String], integer_none_any: true,
desc: 'Return issues which are assigned to the user with the given ID'
+ optional :assignee_username, type: Array[String],
+ desc: 'Return issues which are assigned to the user with the given username'
optional :scope, type: String, values: %w[created-by-me assigned-to-me created_by_me assigned_to_me all],
desc: 'Return issues for the given scope: `created_by_me`, `assigned_to_me` or `all`'
optional :my_reaction_emoji, type: String, desc: 'Return issues reacted by the authenticated user by the given emoji'
optional :confidential, type: Boolean, desc: 'Filter confidential or public issues'
+ optional :state, type: String, values: %w[opened closed all], default: 'all',
+ desc: 'Return opened, closed, or all issues'
use :pagination
use :issues_params_ee if Gitlab.ee?
@@ -75,13 +66,25 @@ module API
end
end
+ desc "Get currently authenticated user's issues statistics"
+ params do
+ use :issues_params
+ optional :scope, type: String, values: %w[created-by-me assigned-to-me created_by_me assigned_to_me all], default: 'created_by_me',
+ desc: 'Return issues for the given scope: `created_by_me`, `assigned_to_me` or `all`'
+ end
+ get '/issues_statistics' do
+ authenticate! unless params[:scope] == 'all'
+
+ stats = issues_statistics
+
+ present stats, with: Grape::Presenters::Presenter
+ end
+
resource :issues do
desc "Get currently authenticated user's issues" do
success Entities::IssueBasic
end
params do
- optional :state, type: String, values: %w[opened closed all], default: 'all',
- desc: 'Return opened, closed, or all issues'
use :issues_params
optional :scope, type: String, values: %w[created-by-me assigned-to-me created_by_me assigned_to_me all], default: 'created_by_me',
desc: 'Return issues for the given scope: `created_by_me`, `assigned_to_me` or `all`'
@@ -92,6 +95,7 @@ module API
options = {
with: Entities::IssueBasic,
+ with_labels_data: declared_params[:with_labels_data],
current_user: current_user,
issuable_metadata: issuable_meta_data(issues, 'Issue')
}
@@ -108,8 +112,6 @@ module API
success Entities::IssueBasic
end
params do
- optional :state, type: String, values: %w[opened closed all], default: 'all',
- desc: 'Return opened, closed, or all issues'
use :issues_params
end
get ":id/issues" do
@@ -119,12 +121,25 @@ module API
options = {
with: Entities::IssueBasic,
+ with_labels_data: declared_params[:with_labels_data],
current_user: current_user,
issuable_metadata: issuable_meta_data(issues, 'Issue')
}
present issues, options
end
+
+ desc 'Get statistics for the list of group issues'
+ params do
+ use :issues_params
+ end
+ get ":id/issues_statistics" do
+ group = find_group!(params[:id])
+
+ stats = issues_statistics(group_id: group.id, include_subgroups: true)
+
+ present stats, with: Grape::Presenters::Presenter
+ end
end
params do
@@ -137,8 +152,6 @@ module API
success Entities::IssueBasic
end
params do
- optional :state, type: String, values: %w[opened closed all], default: 'all',
- desc: 'Return opened, closed, or all issues'
use :issues_params
end
get ":id/issues" do
@@ -148,6 +161,7 @@ module API
options = {
with: Entities::IssueBasic,
+ with_labels_data: declared_params[:with_labels_data],
current_user: current_user,
project: user_project,
issuable_metadata: issuable_meta_data(issues, 'Issue')
@@ -156,6 +170,18 @@ module API
present issues, options
end
+ desc 'Get statistics for the list of project issues'
+ params do
+ use :issues_params
+ end
+ get ":id/issues_statistics" do
+ project = find_project!(params[:id])
+
+ stats = issues_statistics(project_id: project.id)
+
+ present stats, with: Grape::Presenters::Presenter
+ end
+
desc 'Get a single project issue' do
success Entities::Issue
end