From 452d1d0824f44664484c35a2acc7c008c8167196 Mon Sep 17 00:00:00 2001
From: Ruben Davila <rdavila84@gmail.com>
Date: Fri, 18 Nov 2016 21:19:04 -0500
Subject: [PATCH] Backport some changes done from Time Tracking feature in EE.

---
 app/controllers/concerns/issuable_actions.rb  |  2 +-
 app/controllers/projects/issues_controller.rb |  2 +-
 .../projects/merge_requests_controller.rb     |  2 +-
 app/controllers/projects/notes_controller.rb  | 25 ++++++++++---------
 app/models/concerns/issuable.rb               | 11 ++++++++
 app/serializers/issuable_entity.rb            | 16 ++++++++++++
 app/serializers/issue_entity.rb               |  9 +++++++
 app/serializers/issue_serializer.rb           |  3 +++
 app/serializers/label_entity.rb               | 11 ++++++++
 app/serializers/merge_request_entity.rb       | 14 +++++++++++
 app/serializers/merge_request_serializer.rb   |  3 +++
 app/services/notes/create_service.rb          |  2 +-
 app/views/shared/issuable/_form.html.haml     |  2 +-
 13 files changed, 85 insertions(+), 17 deletions(-)
 create mode 100644 app/serializers/issuable_entity.rb
 create mode 100644 app/serializers/issue_entity.rb
 create mode 100644 app/serializers/issue_serializer.rb
 create mode 100644 app/serializers/label_entity.rb
 create mode 100644 app/serializers/merge_request_entity.rb
 create mode 100644 app/serializers/merge_request_serializer.rb

diff --git a/app/controllers/concerns/issuable_actions.rb b/app/controllers/concerns/issuable_actions.rb
index be86fa106f8..0821974aa93 100644
--- a/app/controllers/concerns/issuable_actions.rb
+++ b/app/controllers/concerns/issuable_actions.rb
@@ -12,7 +12,7 @@ module IssuableActions
     destroy_method = "destroy_#{issuable.class.name.underscore}".to_sym
     TodoService.new.public_send(destroy_method, issuable, current_user)
 
-    name = issuable.class.name.titleize.downcase
+    name = issuable.human_class_name
     flash[:notice] = "The #{name} was successfully deleted."
     redirect_to polymorphic_path([@project.namespace.becomes(Namespace), @project, issuable.class])
   end
diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb
index 3f1a1d1c511..4aea7bb62c4 100644
--- a/app/controllers/projects/issues_controller.rb
+++ b/app/controllers/projects/issues_controller.rb
@@ -69,7 +69,7 @@ class Projects::IssuesController < Projects::ApplicationController
     respond_to do |format|
       format.html
       format.json do
-        render json: @issue.to_json(include: [:milestone, :labels])
+        render json: IssueSerializer.new.represent(@issue)
       end
     end
   end
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index dff0213411c..f6e477dd3c3 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -61,7 +61,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
       format.html { define_discussion_vars }
 
       format.json do
-        render json: @merge_request
+        render json: MergeRequestSerializer.new.represent(@merge_request)
       end
 
       format.patch  do
diff --git a/app/controllers/projects/notes_controller.rb b/app/controllers/projects/notes_controller.rb
index 0948ad21649..f029fde2a2f 100644
--- a/app/controllers/projects/notes_controller.rb
+++ b/app/controllers/projects/notes_controller.rb
@@ -146,24 +146,26 @@ class Projects::NotesController < Projects::ApplicationController
   end
 
   def note_json(note)
+    attrs = {
+      award: false,
+      id: note.id
+    }
+
     if note.is_a?(AwardEmoji)
-      {
+      attrs.merge!(
         valid:  note.valid?,
         award:  true,
-        id:     note.id,
         name:   note.name
-      }
+      )
     elsif note.persisted?
       Banzai::NoteRenderer.render([note], @project, current_user)
 
-      attrs = {
+      attrs.merge!(
         valid: true,
-        id: note.id,
         discussion_id: note.discussion_id,
         html: note_html(note),
-        award: false,
         note: note.note
-      }
+      )
 
       if note.diff_note?
         discussion = note.to_discussion
@@ -188,15 +190,14 @@ class Projects::NotesController < Projects::ApplicationController
           attrs[:original_discussion_id] = note.original_discussion_id
         end
       end
-
-      attrs
     else
-      {
+      attrs.merge!(
         valid: false,
-        award: false,
         errors: note.errors
-      }
+      )
     end
+
+    attrs
   end
 
   def authorize_admin_note!
diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb
index 664bb594aa9..0da23d3c41b 100644
--- a/app/models/concerns/issuable.rb
+++ b/app/models/concerns/issuable.rb
@@ -251,6 +251,17 @@ module Issuable
     self.class.to_ability_name
   end
 
+  # Convert this Issuable class name to a format usable by notifications.
+  #
+  # Examples:
+  #
+  #   issuable.class           # => MergeRequest
+  #   issuable.human_class_name # => "merge request"
+
+  def human_class_name
+    @human_class_name ||= self.class.name.titleize.downcase
+  end
+
   # Returns a Hash of attributes to be used for Twitter card metadata
   def card_attributes
     {
diff --git a/app/serializers/issuable_entity.rb b/app/serializers/issuable_entity.rb
new file mode 100644
index 00000000000..17c9160cb19
--- /dev/null
+++ b/app/serializers/issuable_entity.rb
@@ -0,0 +1,16 @@
+class IssuableEntity < Grape::Entity
+  expose :id
+  expose :iid
+  expose :assignee_id
+  expose :author_id
+  expose :description
+  expose :lock_version
+  expose :milestone_id
+  expose :position
+  expose :state
+  expose :title
+  expose :updated_by_id
+  expose :created_at
+  expose :updated_at
+  expose :deleted_at
+end
diff --git a/app/serializers/issue_entity.rb b/app/serializers/issue_entity.rb
new file mode 100644
index 00000000000..6429159ebe1
--- /dev/null
+++ b/app/serializers/issue_entity.rb
@@ -0,0 +1,9 @@
+class IssueEntity < IssuableEntity
+  expose :branch_name
+  expose :confidential
+  expose :due_date
+  expose :moved_to_id
+  expose :project_id
+  expose :milestone, using: API::Entities::Milestone
+  expose :labels, using: LabelEntity
+end
diff --git a/app/serializers/issue_serializer.rb b/app/serializers/issue_serializer.rb
new file mode 100644
index 00000000000..4fff54a9126
--- /dev/null
+++ b/app/serializers/issue_serializer.rb
@@ -0,0 +1,3 @@
+class IssueSerializer < BaseSerializer
+  entity IssueEntity
+end
diff --git a/app/serializers/label_entity.rb b/app/serializers/label_entity.rb
new file mode 100644
index 00000000000..304fd9de08f
--- /dev/null
+++ b/app/serializers/label_entity.rb
@@ -0,0 +1,11 @@
+class LabelEntity < Grape::Entity
+  expose :id
+  expose :title
+  expose :color
+  expose :description
+  expose :group_id
+  expose :project_id
+  expose :template
+  expose :created_at
+  expose :updated_at
+end
diff --git a/app/serializers/merge_request_entity.rb b/app/serializers/merge_request_entity.rb
new file mode 100644
index 00000000000..7445298c714
--- /dev/null
+++ b/app/serializers/merge_request_entity.rb
@@ -0,0 +1,14 @@
+class MergeRequestEntity < IssuableEntity
+  expose :in_progress_merge_commit_sha
+  expose :locked_at
+  expose :merge_commit_sha
+  expose :merge_error
+  expose :merge_params
+  expose :merge_status
+  expose :merge_user_id
+  expose :merge_when_build_succeeds
+  expose :source_branch
+  expose :source_project_id
+  expose :target_branch
+  expose :target_project_id
+end
diff --git a/app/serializers/merge_request_serializer.rb b/app/serializers/merge_request_serializer.rb
new file mode 100644
index 00000000000..aa6e00dfcb4
--- /dev/null
+++ b/app/serializers/merge_request_serializer.rb
@@ -0,0 +1,3 @@
+class MergeRequestSerializer < BaseSerializer
+  entity MergeRequestEntity
+end
diff --git a/app/services/notes/create_service.rb b/app/services/notes/create_service.rb
index e338792412b..7935fabe2da 100644
--- a/app/services/notes/create_service.rb
+++ b/app/services/notes/create_service.rb
@@ -35,7 +35,7 @@ module Notes
         todo_service.new_note(note, current_user)
       end
 
-      if command_params && command_params.any?
+      if command_params.present?
         slash_commands_service.execute(command_params, note)
 
         # We must add the error after we call #save because errors are reset
diff --git a/app/views/shared/issuable/_form.html.haml b/app/views/shared/issuable/_form.html.haml
index 2fe9e82194b..9b9ad510444 100644
--- a/app/views/shared/issuable/_form.html.haml
+++ b/app/views/shared/issuable/_form.html.haml
@@ -125,7 +125,7 @@
   - else
     .pull-right
       - if can?(current_user, :"destroy_#{issuable.to_ability_name}", @project)
-        = link_to 'Delete', polymorphic_path([@project.namespace.becomes(Namespace), @project, issuable]), data: { confirm: "#{issuable.class.name.titleize} will be removed! Are you sure?" },
+        = link_to 'Delete', polymorphic_path([@project.namespace.becomes(Namespace), @project, issuable]), data: { confirm: "#{issuable.human_class_name} will be removed! Are you sure?" },
                                                                                                   method: :delete, class: 'btn btn-danger btn-grouped'
       = link_to 'Cancel', polymorphic_path([@project.namespace.becomes(Namespace), @project, issuable]), class: 'btn btn-grouped btn-cancel'
 
-- 
GitLab