summaryrefslogtreecommitdiff
path: root/lib/api/entities.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/api/entities.rb')
-rw-r--r--lib/api/entities.rb56
1 files changed, 50 insertions, 6 deletions
diff --git a/lib/api/entities.rb b/lib/api/entities.rb
index e8dd61e493f..031dd02c6eb 100644
--- a/lib/api/entities.rb
+++ b/lib/api/entities.rb
@@ -1,11 +1,11 @@
module API
module Entities
class UserSafe < Grape::Entity
- expose :name, :username
+ expose :id, :name, :username
end
class UserBasic < UserSafe
- expose :id, :state
+ expose :state
expose :avatar_url do |user, options|
user.avatar_url(only_path: false)
end
@@ -320,7 +320,10 @@ module API
end
class IssueBasic < ProjectEntity
- expose :label_names, as: :labels
+ expose :labels do |issue, options|
+ # Avoids an N+1 query since labels are preloaded
+ issue.labels.map(&:title).sort
+ end
expose :milestone, using: Entities::Milestone
expose :assignees, :author, using: Entities::UserBasic
@@ -329,13 +332,32 @@ module API
end
expose :user_notes_count
- expose :upvotes, :downvotes
+ expose :upvotes do |issue, options|
+ if options[:issuable_metadata]
+ # Avoids an N+1 query when metadata is included
+ options[:issuable_metadata][issue.id].upvotes
+ else
+ issue.upvotes
+ end
+ end
+ expose :downvotes do |issue, options|
+ if options[:issuable_metadata]
+ # Avoids an N+1 query when metadata is included
+ options[:issuable_metadata][issue.id].downvotes
+ else
+ issue.downvotes
+ end
+ end
expose :due_date
expose :confidential
expose :web_url do |issue, options|
Gitlab::UrlBuilder.build(issue)
end
+
+ expose :time_stats, using: 'API::Entities::IssuableTimeStats' do |issue|
+ issue
+ end
end
class Issue < IssueBasic
@@ -365,10 +387,22 @@ module API
end
class IssuableTimeStats < Grape::Entity
+ format_with(:time_tracking_formatter) do |time_spent|
+ Gitlab::TimeTrackingFormatter.output(time_spent)
+ end
+
expose :time_estimate
expose :total_time_spent
expose :human_time_estimate
- expose :human_total_time_spent
+
+ with_options(format_with: :time_tracking_formatter) do
+ expose :total_time_spent, as: :human_total_time_spent
+ end
+
+ def total_time_spent
+ # Avoids an N+1 query since timelogs are preloaded
+ object.timelogs.map(&:time_spent).sum
+ end
end
class ExternalIssue < Grape::Entity
@@ -418,6 +452,10 @@ module API
expose :web_url do |merge_request, options|
Gitlab::UrlBuilder.build(merge_request)
end
+
+ expose :time_stats, using: 'API::Entities::IssuableTimeStats' do |merge_request|
+ merge_request
+ end
end
class MergeRequest < MergeRequestBasic
@@ -453,6 +491,10 @@ module API
expose :user, using: Entities::UserPublic
end
+ class GPGKey < Grape::Entity
+ expose :id, :key, :created_at
+ end
+
class Note < Grape::Entity
# Only Issue and MergeRequest have iid
NOTEABLE_TYPES_WITH_IID = %w(Issue MergeRequest).freeze
@@ -737,6 +779,7 @@ module API
expose :tag_list
expose :run_untagged
expose :locked
+ expose :access_level
expose :version, :revision, :platform, :architecture
expose :contacted_at
expose :token, if: lambda { |runner, options| options[:current_user].admin? || !runner.is_shared? }
@@ -780,7 +823,7 @@ module API
class Variable < Grape::Entity
expose :key, :value
- expose :protected?, as: :protected
+ expose :protected?, as: :protected, if: -> (entity, _) { entity.respond_to?(:protected?) }
end
class Pipeline < PipelineBasic
@@ -801,6 +844,7 @@ module API
class PipelineScheduleDetails < PipelineSchedule
expose :last_pipeline, using: Entities::PipelineBasic
+ expose :variables, using: Entities::Variable
end
class EnvironmentBasic < Grape::Entity