diff --git a/app/controllers/groups/milestones_controller.rb b/app/controllers/groups/milestones_controller.rb
index a86cc58c02109cfa23a41ffd232284eedacf74f7..235b27f53a91f946ec0a118a7de3ba6c618e74af 100644
--- a/app/controllers/groups/milestones_controller.rb
+++ b/app/controllers/groups/milestones_controller.rb
@@ -13,14 +13,16 @@ class Groups::MilestonesController < ApplicationController
 
   def show
     project_milestones = Milestone.where(project_id: group.projects)
-    @group_milestones = Milestones::GroupService.new(project_milestones).milestone(title)
+    @group_milestone = Milestones::GroupService.new(project_milestones).milestone(title)
+    @project_issues = @group_milestone.filter_by(params[:status], "issues")
+    @project_merge_requests = @group_milestone.filter_by(params[:status], "merge_requests")
   end
 
   def update
     project_milestones = Milestone.where(project_id: group.projects)
     @group_milestones = Milestones::GroupService.new(project_milestones).milestone(title)
 
-    @group_milestones.each do |milestone|
+    @group_milestones.milestones.each do |milestone|
       Milestones::UpdateService.new(milestone.project, current_user, params[:milestone]).execute(milestone)
     end
 
diff --git a/app/models/group_milestone.rb b/app/models/group_milestone.rb
index 567e0c2b9fb6ddd95585f14f6497f284352b1887..0faff39ae7aa24c1aea5d03ed258681897023490 100644
--- a/app/models/group_milestone.rb
+++ b/app/models/group_milestone.rb
@@ -9,6 +9,10 @@ class GroupMilestone
     @title
   end
 
+  def safe_title
+    @title.gsub(".", "-")
+  end
+
   def milestones
     @milestones
   end
@@ -25,6 +29,10 @@ class GroupMilestone
     milestones.map{ |milestone| milestone.merge_requests.count }.sum
   end
 
+  def open_items_count
+    milestones.map{ |milestone| milestone.open_items_count }.sum
+  end
+
   def closed_items_count
     milestones.map{ |milestone| milestone.closed_items_count }.sum
   end
@@ -42,10 +50,69 @@ class GroupMilestone
   def state
     state = milestones.map{ |milestone| milestone.state }
 
-    if state.count("active") == state.size
+    if state.count('active') == state.size
       'active'
     else
       'closed'
     end
   end
+
+  def active?
+    state == 'active'
+  end
+
+  def closed?
+    state == 'closed'
+  end
+
+  def opened_unassigned_issues
+    milestones.map{ |milestone| milestone.issues.opened.unassigned }
+  end
+
+  def opened_assigned_issues
+    milestones.map{ |milestone| milestone.issues.opened.assigned }
+  end
+
+  def closed_issues
+    milestones.map{ |milestone| milestone.issues.closed }
+  end
+
+  def participants
+    milestones.map{ |milestone| milestone.participants.uniq }.reject(&:empty?).flatten
+  end
+
+  def filter_by(filter, entity)
+    if entity
+      milestones = self.milestones.sort_by(&:project_id)
+      entities = {}
+      milestones.each do |project_milestone|
+        next unless project_milestone.send(entity).any?
+        project_name = project_milestone.project.name
+        entities_by_state = state_filter(filter, project_milestone.send(entity))
+        entities.store(project_name, entities_by_state)
+      end
+      entities
+    else
+      {}
+    end
+  end
+
+  def state_filter(filter, entities)
+    if entities.present?
+      sorted_entities = entities.sort_by(&:position)
+      entities_by_state =  case filter
+                           when 'active'; sorted_entities.group_by(&:state)['opened']
+                           when 'closed'; sorted_entities.group_by(&:state)['closed']
+                           else sorted_entities
+                           end
+      if entities_by_state.blank?
+        []
+      else
+        entities_by_state
+      end
+    else
+      []
+    end
+  end
+
 end
diff --git a/app/services/milestones/group_service.rb b/app/services/milestones/group_service.rb
index 39ae913a72a8ce331a6dfac80eebc023cd5f1928..2d1aa878c24324be4bb1bcdfde9e52b8771506bf 100644
--- a/app/services/milestones/group_service.rb
+++ b/app/services/milestones/group_service.rb
@@ -5,16 +5,22 @@ module Milestones
     end
 
     def execute
-      @project_milestones.map{ |title, milestone| GroupMilestone.new(title, milestone) }
+      build(@project_milestones)
     end
 
     def milestone(title)
       if title
-        @project_milestones[title]
+        group_milestone = @project_milestones[title].group_by(&:title)
+        build(group_milestone).first
       else
         nil
       end
     end
 
+  private
+
+    def build(milestone)
+      milestone.map{ |title, milestones| GroupMilestone.new(title, milestones) }
+    end
   end
 end
diff --git a/app/views/groups/milestones/_issue.html.haml b/app/views/groups/milestones/_issue.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..7009400a46ccdea2683cf28a9eacb6d44911fba3
--- /dev/null
+++ b/app/views/groups/milestones/_issue.html.haml
@@ -0,0 +1,9 @@
+%li{ id: dom_id(issue, 'sortable'), class: 'issue-row', 'data-iid' => issue.iid }
+  %span.str-truncated
+    - project = issue.project
+    = link_to [project, issue] do
+      %span.cgray ##{issue.iid}
+    = link_to_gfm issue.title, [project, issue]
+  .pull-right.assignee-icon
+    - if issue.assignee
+      = image_tag avatar_icon(issue.assignee.email, 16), class: "avatar s16"
diff --git a/app/views/groups/milestones/_issues.html.haml b/app/views/groups/milestones/_issues.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..3fefb2f01079b824844fae903be83c2d8afe99fe
--- /dev/null
+++ b/app/views/groups/milestones/_issues.html.haml
@@ -0,0 +1,6 @@
+.panel.panel-default
+  .panel-heading= name
+  %ul{ class: "well-list issues-sortable-list" }
+    - issues.each do |issue|
+      = render 'issue', issue: issue
+
diff --git a/app/views/groups/milestones/_merge_request.html.haml b/app/views/groups/milestones/_merge_request.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..4f11aaa74b7b7d167a0ea09f81df70d8c37c12bf
--- /dev/null
+++ b/app/views/groups/milestones/_merge_request.html.haml
@@ -0,0 +1,6 @@
+%li{ id: dom_id(merge_request, 'sortable'),  class: 'mr-row', 'data-iid' => merge_request.iid }
+  %span.str-truncated
+    - project = merge_request.project
+    = link_to [project, merge_request] do
+      %span.cgray ##{merge_request.iid}
+    = link_to_gfm truncate(merge_request.title, length: 60), [project, merge_request]
diff --git a/app/views/groups/milestones/_merge_requests.html.haml b/app/views/groups/milestones/_merge_requests.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..9bb213ffe328e7e0427389bdbdfa8476d4962ef9
--- /dev/null
+++ b/app/views/groups/milestones/_merge_requests.html.haml
@@ -0,0 +1,5 @@
+.panel.panel-default
+  .panel-heading= name
+  %ul{ class: "well-list merge_requests-sortable-list" }
+    - merge_requests.sort_by(&:position).each do |merge_request|
+      = render 'merge_request', merge_request: merge_request
diff --git a/app/views/groups/milestones/index.html.haml b/app/views/groups/milestones/index.html.haml
index b93ff09d25c12bc7c486bc4b74ed0b6034305505..e3dd1ae5ae07586ceeb4eafb3241b973dad877c2 100644
--- a/app/views/groups/milestones/index.html.haml
+++ b/app/views/groups/milestones/index.html.haml
@@ -22,21 +22,20 @@
             .nothing-here-block No milestones to show
         - else
           - @group_milestones.each do |milestone|
-            %li{class: "milestone milestone-#{milestone.state == 'closed' ? 'closed' : 'open'}", id: dom_id(milestone.milestones.first) }
+            %li{class: "milestone milestone-#{milestone.closed? ? 'closed' : 'open'}", id: dom_id(milestone.milestones.first) }
               .pull-right
-                - safe_title = milestone.title.gsub(".", "-")
-                - if milestone.state == 'closed'
-                  = link_to 'Reopen Milestone', group_milestone_path(@group, safe_title, milestone: {state_event: :activate }), method: :put, class: "btn btn-small btn-grouped"
+                - if milestone.closed?
+                  = link_to 'Reopen Milestone', group_milestone_path(@group, milestone.safe_title, milestone: {state_event: :activate }), method: :put, class: "btn btn-small btn-grouped"
                 - else
-                  = link_to 'Close Milestone', group_milestone_path(@group, safe_title, milestone: {state_event: :close }), method: :put, class: "btn btn-small btn-remove"
+                  = link_to 'Close Milestone', group_milestone_path(@group, milestone.safe_title, milestone: {state_event: :close }), method: :put, class: "btn btn-small btn-remove"
               %h4
-                = link_to_gfm truncate(milestone.title, length: 100), group_milestone_path(@group, safe_title)
+                = link_to_gfm truncate(milestone.title, length: 100), group_milestone_path(@group, milestone.safe_title)
               %div
                 %div
-                  = link_to root_path do
+                  = link_to group_milestone_path(@group, milestone.safe_title) do
                     = pluralize milestone.issue_count, 'Issue'
                   &nbsp;
-                  = link_to root_path do
+                  = link_to group_milestone_path(@group, milestone.safe_title) do
                     = pluralize milestone.merge_requests_count, 'Merge Request'
                   &nbsp;
                   %span.light #{milestone.percent_complete}% complete
diff --git a/app/views/groups/milestones/show.html.haml b/app/views/groups/milestones/show.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..a450e7d09a51617c71b622a9061a6b2520412eb0
--- /dev/null
+++ b/app/views/groups/milestones/show.html.haml
@@ -0,0 +1,77 @@
+%h3.page-title
+  Milestone #{@group_milestone.title}
+  .pull-right
+    - if @group_milestone.active?
+      = link_to 'Close Milestone', group_milestone_path(@group, @group_milestone.safe_title, milestone: {state_event: :close }), method: :put, class: "btn btn-small btn-remove"
+    - else
+      = link_to 'Reopen Milestone', group_milestone_path(@group, @group_milestone.safe_title, milestone: {state_event: :activate }), method: :put, class: "btn btn-small btn-grouped"
+
+- if (@group_milestone.total_items_count == @group_milestone.closed_items_count) && @group_milestone.active?
+  .alert.alert-success
+    %span All issues for this milestone are closed. You may close the milestone now.
+
+.back-link
+  = link_to group_milestones_path(@group) do
+    &larr; To milestones list
+
+.issue-box{ class: "issue-box-#{@group_milestone.closed? ? 'closed' : 'open'}" }
+  .state.clearfix
+    .state-label
+      - if @group_milestone.closed?
+        Closed
+      - else
+        Open
+
+  %h4.title
+    = gfm escape_once(@group_milestone.title)
+
+  .context
+    %p
+      Progress:
+      #{@group_milestone.closed_items_count} closed
+      &ndash;
+      #{@group_milestone.open_items_count} open
+
+    .progress.progress-info
+      .progress-bar{style: "width: #{@group_milestone.percent_complete}%;"}
+
+%ul.nav.nav-tabs
+  %li.active
+    = link_to '#tab-issues', 'data-toggle' => 'tab' do
+      Issues
+      %span.badge= @group_milestone.issue_count
+  %li
+    = link_to '#tab-merge-requests', 'data-toggle' => 'tab' do
+      Merge Requests
+      %span.badge= @group_milestone.merge_requests_count
+  %li
+    = link_to '#tab-participants', 'data-toggle' => 'tab' do
+      Participants
+      %span.badge= @group_milestone.participants.count
+
+.tab-content
+  .tab-pane.active#tab-issues
+    .row
+      .col-md-4.responsive-side
+        = render 'groups/filter', entity: 'milestone'
+      .col-md-8
+        - @project_issues.each do |name, issues|
+          = render 'issues', name: name, issues: issues
+
+  .tab-pane#tab-merge-requests
+    .row
+      .col-md-4.responsive-side
+        = render 'groups/filter', entity: 'milestone'
+      .col-md-8
+        - @project_merge_requests.each do |name, merge_requests|
+          = render 'merge_requests', name: name, merge_requests: merge_requests
+
+  .tab-pane#tab-participants
+    %ul.bordered-list
+      - @group_milestone.participants.each do |user|
+        %li
+          = link_to user, title: user.name, class: "darken" do
+            = image_tag avatar_icon(user.email, 32), class: "avatar s32"
+            %strong= truncate(user.name, lenght: 40)
+            %br
+            %small.cgray= user.username