diff --git a/CHANGELOG b/CHANGELOG
index 4ebf0440cdd20ae64ddaed51e490678b2e6372c3..d32c1fd84922eb84f9f145d32cd190fb0f6ef520 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -8,6 +8,7 @@ v 8.10.0 (unreleased)
   - Fix pagination when sorting by columns with lots of ties (like priority)
   - Exclude email check from the standard health check
   - Implement Subresource Integrity for CSS and JavaScript assets. This prevents malicious assets from loading in the case of a CDN compromise.
+  - Fix changing issue state columns in milestone view
   - Fix user creation with stronger minimum password requirements !4054 (nathan-pmt)
   - Add API endpoint for a group issues !4520 (mahcsig)
 
diff --git a/app/assets/javascripts/milestone.js.coffee b/app/assets/javascripts/milestone.js.coffee
index 0037a3a21c268fb917600ccf9dd72cc94450162a..a19e68b39e291516d4e07fe64e46039ba38faa13 100644
--- a/app/assets/javascripts/milestone.js.coffee
+++ b/app/assets/javascripts/milestone.js.coffee
@@ -4,18 +4,10 @@ class @Milestone
       type: "PUT"
       url: issue_url
       data: data
-      success: (data) ->
-        if data.saved == true
-          if data.assignee_avatar_url
-            img_tag = $('<img/>')
-            img_tag.attr('src', data.assignee_avatar_url)
-            img_tag.addClass('avatar s16')
-            $(li).find('.assignee-icon').html(img_tag)
-          else
-            $(li).find('.assignee-icon').html('')
-          $(li).effect 'highlight'
-        else
-          new Flash("Issue update failed", 'alert')
+      success: (_data) =>
+        @successCallback(_data, li)
+      error: (data) ->
+        new Flash("Issue update failed", 'alert')
       dataType: "json"
 
   @sortIssues: (data) ->
@@ -25,9 +17,10 @@ class @Milestone
       type: "PUT"
       url: sort_issues_url
       data: data
-      success: (data) ->
-        if data.saved != true
-          new Flash("Issues update failed", 'alert')
+      success: (_data) =>
+        @successCallback(_data)
+      error: ->
+        new Flash("Issues update failed", 'alert')
       dataType: "json"
 
   @sortMergeRequests: (data) ->
@@ -37,9 +30,10 @@ class @Milestone
       type: "PUT"
       url: sort_mr_url
       data: data
-      success: (data) ->
-        if data.saved != true
-          new Flash("MR update failed", 'alert')
+      success: (_data) =>
+        @successCallback(_data)
+      error: (data) ->
+        new Flash("Issue update failed", 'alert')
       dataType: "json"
 
   @updateMergeRequest: (li, merge_request_url, data) ->
@@ -47,20 +41,23 @@ class @Milestone
       type: "PUT"
       url: merge_request_url
       data: data
-      success: (data) ->
-        if data.saved == true
-          if data.assignee_avatar_url
-            img_tag = $('<img/>')
-            img_tag.attr('src', data.assignee_avatar_url)
-            img_tag.addClass('avatar s16')
-            $(li).find('.assignee-icon').html(img_tag)
-          else
-            $(li).find('.assignee-icon').html('')
-          $(li).effect 'highlight'
-        else
-          new Flash("Issue update failed", 'alert')
+      success: (_data) =>
+        @successCallback(_data, li)
+      error: (data) ->
+        new Flash("Issue update failed", 'alert')
       dataType: "json"
 
+  @successCallback: (data, element) =>
+    if data.assignee
+      img_tag = $('<img/>')
+      img_tag.attr('src', data.assignee.avatar_url)
+      img_tag.addClass('avatar s16')
+      $(element).find('.assignee-icon').html(img_tag)
+    else
+      $(element).find('.assignee-icon').html('')
+
+    $(element).effect 'highlight'
+
   constructor: ->
     oldMouseStart = $.ui.sortable.prototype._mouseStart
     $.ui.sortable.prototype._mouseStart = (event, overrideHandle, noActivation) ->
@@ -81,8 +78,10 @@ class @Milestone
       stop: (event, ui) ->
         $(".issues-sortable-list").css "min-height", "0px"
       update: (event, ui) ->
-        data = $(this).sortable("serialize")
-        Milestone.sortIssues(data)
+        # Prevents sorting from container which element has been removed.
+        if $(this).find(ui.item).length > 0
+          data = $(this).sortable("serialize")
+          Milestone.sortIssues(data)
 
       receive: (event, ui) ->
         new_state = $(this).data('state')
diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb
index fbf8b01b7c2a94ed0038909d87e2a92bac350da6..8b8df6807397b8fb8048686bfa16f13ec6c5e3c1 100644
--- a/app/controllers/projects/issues_controller.rb
+++ b/app/controllers/projects/issues_controller.rb
@@ -115,6 +115,7 @@ class Projects::IssuesController < Projects::ApplicationController
           render :edit
         end
       end
+
       format.json do
         render json: @issue.to_json(include: { milestone: {}, assignee: { methods: :avatar_url }, labels: { methods: :text_color } })
       end
diff --git a/app/views/shared/milestones/_issuable.html.haml b/app/views/shared/milestones/_issuable.html.haml
index 47b66d44e43fcb953fce413d48b45d51bad1a8d9..3c03c220ddda28bad006fa7429b63fbb418ef6e8 100644
--- a/app/views/shared/milestones/_issuable.html.haml
+++ b/app/views/shared/milestones/_issuable.html.haml
@@ -21,7 +21,8 @@
       = link_to polymorphic_path(base_url_args, { milestone_title: @milestone.title, label_name: label.title, state: 'all' }) do
         - render_colored_label(label)
 
-    - if assignee
-      = link_to polymorphic_path(base_url_args, { milestone_title: @milestone.title, assignee_id: issuable.assignee_id, state: 'all' }),
-                class: 'has-tooltip', title: "Assigned to #{assignee.name}", data: { container: 'body' } do
-        - image_tag(avatar_icon(issuable.assignee, 16), class: "avatar s16", alt: '')
+    %span{ class: "assignee-icon" }
+      - if assignee
+        = link_to polymorphic_path(base_url_args, { milestone_title: @milestone.title, assignee_id: issuable.assignee_id, state: 'all' }),
+                  class: 'has-tooltip', title: "Assigned to #{assignee.name}", data: { container: 'body' } do
+          - image_tag(avatar_icon(issuable.assignee, 16), class: "avatar s16", alt: '')