From 087abdf7fd47cfc1ec597fc18b5fa910b945bbd1 Mon Sep 17 00:00:00 2001
From: Jacob Schatz <jacobschatz@Jacobs-MBP.fios-router.home>
Date: Wed, 27 Jan 2016 17:38:19 -0500
Subject: [PATCH] New right side gutter design.

[WIP]
---
 .../javascripts/issuable_context.js.coffee    |  12 --
 app/assets/stylesheets/framework/sidebar.scss |  13 +-
 .../stylesheets/framework/variables.scss      |   2 +
 app/assets/stylesheets/pages/issuable.scss    |  13 ++
 app/helpers/application_helper.rb             |  30 ++++
 app/helpers/nav_helper.rb                     |   6 +
 app/views/layouts/_page.html.haml             |   2 +-
 app/views/projects/issues/show.html.haml      |   8 +-
 .../projects/merge_requests/_show.html.haml   |   6 +-
 app/views/shared/issuable/_sidebar.html.haml  | 160 ++++++++++--------
 10 files changed, 155 insertions(+), 97 deletions(-)

diff --git a/app/assets/javascripts/issuable_context.js.coffee b/app/assets/javascripts/issuable_context.js.coffee
index 02232698bc2..c2144aea25e 100644
--- a/app/assets/javascripts/issuable_context.js.coffee
+++ b/app/assets/javascripts/issuable_context.js.coffee
@@ -10,18 +10,6 @@ class @IssuableContext
     $(".issuable-sidebar .inline-update").on "change", ".js-assignee", ->
       $(this).submit()
 
-    $('.issuable-details').waitForImages ->
-      $('.issuable-affix').on 'affix.bs.affix', ->
-        $(@).width($(@).outerWidth())
-      .on 'affixed-top.bs.affix affixed-bottom.bs.affix', ->
-        $(@).width('')
-
-      $('.issuable-affix').affix offset:
-        top: ->
-          @top = ($('.issuable-affix').offset().top - 70)
-        bottom: ->
-          @bottom = $('.footer').outerHeight(true)
-
     $(".edit-link").click (e) ->
       block = $(@).parents('.block')
       block.find('.selectbox').show()
diff --git a/app/assets/stylesheets/framework/sidebar.scss b/app/assets/stylesheets/framework/sidebar.scss
index 540d0b03163..e0fc969ff0e 100644
--- a/app/assets/stylesheets/framework/sidebar.scss
+++ b/app/assets/stylesheets/framework/sidebar.scss
@@ -200,6 +200,10 @@
   }
 }
 
+@mixin expanded-gutter {
+  padding-right: $gutter_width;
+}
+
 @mixin collapsed-sidebar {
   padding-left: $sidebar_collapsed_width;
 
@@ -266,6 +270,7 @@
   background: #f2f6f7;
 }
 
+// page is small enough
 @media (max-width: $screen-md-max) {
   .page-sidebar-collapsed {
     @include collapsed-sidebar;
@@ -280,7 +285,13 @@
   }
 }
 
+// page is large enough
 @media(min-width: $screen-md-max) {
+
+  .page-gutter {
+    @include expanded-gutter;
+  }
+
   .page-sidebar-collapsed {
     @include collapsed-sidebar;
   }
@@ -288,4 +299,4 @@
   .page-sidebar-expanded {
     @include expanded-sidebar;
   }
-}
+}
\ No newline at end of file
diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss
index 3ec48da9a41..7af6688963f 100644
--- a/app/assets/stylesheets/framework/variables.scss
+++ b/app/assets/stylesheets/framework/variables.scss
@@ -12,6 +12,8 @@ $gl-font-size: 15px;
 $list-font-size: 15px;
 $sidebar_collapsed_width: 62px;
 $sidebar_width: 230px;
+$gutter_collapsed_width: 62px;
+$gutter_width: 320px;
 $avatar_radius: 50%;
 $code_font_size: 13px;
 $code_line_height: 1.5;
diff --git a/app/assets/stylesheets/pages/issuable.scss b/app/assets/stylesheets/pages/issuable.scss
index 977ada0ff38..d1f2175bfb7 100644
--- a/app/assets/stylesheets/pages/issuable.scss
+++ b/app/assets/stylesheets/pages/issuable.scss
@@ -133,3 +133,16 @@
     margin-right: 2px;
   }
 }
+
+
+.right-sidebar {
+  position: fixed;
+  top: 58px;
+  right: 0;
+  height: 100%;
+  transition-duration: .3s;
+  background: $gray-light;
+  overflow: scroll;
+  width: $gutter_width;
+  padding: 10px 20px;
+}
\ No newline at end of file
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index a2458ad3be0..57a9ce8294a 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -293,6 +293,36 @@ module ApplicationHelper
     end
   end
 
+  def issuable_count(entity, project)
+    if project.nil?
+      0
+    elsif current_controller?(:issues)
+      project.issues.send(entity).count
+    elsif current_controller?(:merge_requests)
+      project.merge_requests.send(entity).count
+    end
+  end
+
+  def next_issuable_for(project)
+    if project.nil?
+      nil
+    elsif current_controller?(:issues)
+      project.issues.where("id > ?", id).first
+    elsif current_controller?(:merge_requests)
+      project.merge_requests.where("id > ?", id).first
+    end
+  end
+
+  def prev_issuable_for(project)
+    if project.nil?
+      nil
+    elsif current_controller?(:issues)
+      project.issues.where("id < ?", id).last
+    elsif current_controller?(:merge_requests)
+      project.merge_requests.where("id > ?", id).last
+    end
+  end
+
   def state_filters_text_for(entity, project)
     titles = {
       opened: "Open"
diff --git a/app/helpers/nav_helper.rb b/app/helpers/nav_helper.rb
index e6fb8670e57..20b89cc9db3 100644
--- a/app/helpers/nav_helper.rb
+++ b/app/helpers/nav_helper.rb
@@ -19,6 +19,12 @@ module NavHelper
     end
   end
 
+  def page_gutter_class
+    if current_path?('merge_requests#show') || current_path?('issues#show')
+      "page-gutter"
+    end
+  end
+
   def nav_header_class
     if nav_menu_collapsed?
       "header-collapsed"
diff --git a/app/views/layouts/_page.html.haml b/app/views/layouts/_page.html.haml
index 26159989777..0c1b5eec95a 100644
--- a/app/views/layouts/_page.html.haml
+++ b/app/views/layouts/_page.html.haml
@@ -1,4 +1,4 @@
-.page-with-sidebar{ class: page_sidebar_class }
+.page-with-sidebar{ class: "#{page_sidebar_class} #{page_gutter_class}" }
   = render "layouts/broadcast"
   .sidebar-wrapper.nicescroll{ class: nav_sidebar_class }
     .header-logo
diff --git a/app/views/projects/issues/show.html.haml b/app/views/projects/issues/show.html.haml
index 51dcca7a1ab..a567c22c823 100644
--- a/app/views/projects/issues/show.html.haml
+++ b/app/views/projects/issues/show.html.haml
@@ -54,11 +54,9 @@
       = render 'votes/votes_block', votable: @issue
 
     .row
-      %section.col-md-9
+      %section.col-md-12
         .issuable-discussion
           = render 'projects/issues/discussion'
-
-      %aside.col-md-3
-        = render 'shared/issuable/sidebar', issuable: @issue
-
       = render 'shared/show_aside'
+
+= render 'shared/issuable/sidebar', issuable: @issue
\ No newline at end of file
diff --git a/app/views/projects/merge_requests/_show.html.haml b/app/views/projects/merge_requests/_show.html.haml
index 8641c3d8b4b..c2ecb48b094 100644
--- a/app/views/projects/merge_requests/_show.html.haml
+++ b/app/views/projects/merge_requests/_show.html.haml
@@ -70,11 +70,9 @@
             = render 'votes/votes_block', votable: @merge_request
 
           .row
-            %section.col-md-9
+            %section.col-md-12
               .issuable-discussion
                 = render "projects/merge_requests/discussion"
-            %aside.col-md-3
-              = render 'shared/issuable/sidebar', issuable: @merge_request
             = render 'shared/show_aside'
 
         #commits.commits.tab-pane
@@ -87,6 +85,8 @@
       .mr-loading-status
         = spinner
 
+= render 'shared/issuable/sidebar', issuable: @merge_request
+
 :javascript
   var merge_request;
 
diff --git a/app/views/shared/issuable/_sidebar.html.haml b/app/views/shared/issuable/_sidebar.html.haml
index 3092ff54242..2aa6dc840eb 100644
--- a/app/views/shared/issuable/_sidebar.html.haml
+++ b/app/views/shared/issuable/_sidebar.html.haml
@@ -1,88 +1,98 @@
-.issuable-sidebar.issuable-affix
-  = form_for [@project.namespace.becomes(Namespace), @project, issuable], remote: true, html: {class: 'issuable-context-form inline-update js-issuable-update'} do |f|
-    .block.assignee
-      .title
-        %label
-          Assignee
-        - if can?(current_user, :"admin_#{issuable.to_ability_name}", @project)
-          .pull-right
-            = link_to 'Edit', '#', class: 'edit-link'
-      .value
-        - if issuable.assignee
-          %strong= link_to_member(@project, issuable.assignee, size: 24)
-          - if issuable.instance_of?(MergeRequest) && !issuable.can_be_merged_by?(issuable.assignee)
-            %a.pull-right.cannot-be-merged{href: '#', data: {toggle: 'tooltip'}, title: 'Not allowed to merge'}
-              = icon('exclamation-triangle')
-        - else
-          .light None
-
-      .selectbox
-        = users_select_tag("#{issuable.class.table_name.singularize}[assignee_id]", placeholder: 'Select assignee', class: 'custom-form-control js-select2 js-assignee', selected: issuable.assignee_id, project: @target_project, null_user: true, current_user: true, first_user: true)
+%aside.right-sidebar
+  .issuable-sidebar
+    .block
+      = issuable.iid
+      of
+      = issuable_count(:all, @project)
+      .issuable-nav.pull-right.btn-group{role: 'group', "aria-label" => '...'}
+        %a.btn.btn-default{href: '#'}
+          Prev
+        %a.btn.btn-default{href: '#'}
+          Next
+    = form_for [@project.namespace.becomes(Namespace), @project, issuable], remote: true, html: {class: 'issuable-context-form inline-update js-issuable-update'} do |f|
+      .block.assignee
+        .title
+          %label
+            Assignee
+          - if can?(current_user, :"admin_#{issuable.to_ability_name}", @project)
+            .pull-right
+              = link_to 'Edit', '#', class: 'edit-link'
+        .value
+          - if issuable.assignee
+            %strong= link_to_member(@project, issuable.assignee, size: 24)
+            - if issuable.instance_of?(MergeRequest) && !issuable.can_be_merged_by?(issuable.assignee)
+              %a.pull-right.cannot-be-merged{href: '#', data: {toggle: 'tooltip'}, title: 'Not allowed to merge'}
+                = icon('exclamation-triangle')
+          - else
+            .light None
 
-    .block.milestone
-      .title
-        %label
-          Milestone
-        - if can?(current_user, :"admin_#{issuable.to_ability_name}", @project)
-          .pull-right
-            = link_to 'Edit', '#', class: 'edit-link'
-      .value
-        - if issuable.milestone
-          %span.back-to-milestone
-            = link_to namespace_project_milestone_path(@project.namespace, @project, issuable.milestone) do
-              %strong
-                = icon('clock-o')
-                = issuable.milestone.title
-        - else
-          .light None
-      .selectbox
-        = f.select(:milestone_id, milestone_options(issuable), { include_blank: true }, { class: 'select2 select2-compact js-select2 js-milestone', data: { placeholder: 'Select milestone' }})
-        = hidden_field_tag :issuable_context
-        = f.submit class: 'btn hide'
+        .selectbox
+          = users_select_tag("#{issuable.class.table_name.singularize}[assignee_id]", placeholder: 'Select assignee', class: 'custom-form-control js-select2 js-assignee', selected: issuable.assignee_id, project: @target_project, null_user: true, current_user: true, first_user: true)
 
-    - if issuable.project.labels.any?
-      .block
+      .block.milestone
         .title
-          %label Labels
+          %label
+            Milestone
           - if can?(current_user, :"admin_#{issuable.to_ability_name}", @project)
             .pull-right
               = link_to 'Edit', '#', class: 'edit-link'
-        .value.issuable-show-labels
-          - if issuable.labels.any?
-            - issuable.labels.each do |label|
-              = link_to_label(label)
+        .value
+          - if issuable.milestone
+            %span.back-to-milestone
+              = link_to namespace_project_milestone_path(@project.namespace, @project, issuable.milestone) do
+                %strong
+                  = icon('clock-o')
+                  = issuable.milestone.title
           - else
             .light None
         .selectbox
-          = f.collection_select :label_ids, issuable.project.labels.all, :id, :name,
-            { selected: issuable.label_ids }, multiple: true, class: 'select2 js-select2', data: { placeholder: "Select labels" }
+          = f.select(:milestone_id, milestone_options(issuable), { include_blank: true }, { class: 'select2 select2-compact js-select2 js-milestone', data: { placeholder: 'Select milestone' }})
+          = hidden_field_tag :issuable_context
+          = f.submit class: 'btn hide'
 
-    = render "shared/issuable/participants", participants: issuable.participants(current_user)
+      - if issuable.project.labels.any?
+        .block
+          .title
+            %label Labels
+            - if can?(current_user, :"admin_#{issuable.to_ability_name}", @project)
+              .pull-right
+                = link_to 'Edit', '#', class: 'edit-link'
+          .value.issuable-show-labels
+            - if issuable.labels.any?
+              - issuable.labels.each do |label|
+                = link_to_label(label)
+            - else
+              .light None
+          .selectbox
+            = f.collection_select :label_ids, issuable.project.labels.all, :id, :name,
+              { selected: issuable.label_ids }, multiple: true, class: 'select2 js-select2', data: { placeholder: "Select labels" }
 
-    - if current_user
-      - subscribed = issuable.subscribed?(current_user)
-      .block.light
-        .title
-          %label.light Notifications
-        - subscribtion_status = subscribed ? 'subscribed' : 'unsubscribed'
-        %button.btn.btn-block.btn-gray.subscribe-button{:type => 'button'}
-          %span= subscribed ? 'Unsubscribe' : 'Subscribe'
-        .subscription-status{data: {status: subscribtion_status}}
-          .unsubscribed{class: ( 'hidden' if subscribed )}
-            You're not receiving notifications from this thread.
-          .subscribed{class: ( 'hidden' unless subscribed )}
-            You're receiving notifications because you're subscribed to this thread.
+      = render "shared/issuable/participants", participants: issuable.participants(current_user)
 
-    - project_ref = cross_project_reference(@project, issuable)
-    .block
-      .title
-      .cross-project-reference
-        %span
-          Reference:
-          %cite{title: project_ref}
-            = project_ref
-        = clipboard_button(clipboard_text: project_ref)
+      - if current_user
+        - subscribed = issuable.subscribed?(current_user)
+        .block.light
+          .title
+            %label.light Notifications
+          - subscribtion_status = subscribed ? 'subscribed' : 'unsubscribed'
+          %button.btn.btn-block.btn-gray.subscribe-button{:type => 'button'}
+            %span= subscribed ? 'Unsubscribe' : 'Subscribe'
+          .subscription-status{data: {status: subscribtion_status}}
+            .unsubscribed{class: ( 'hidden' if subscribed )}
+              You're not receiving notifications from this thread.
+            .subscribed{class: ( 'hidden' unless subscribed )}
+              You're receiving notifications because you're subscribed to this thread.
+
+      - project_ref = cross_project_reference(@project, issuable)
+      .block
+        .title
+        .cross-project-reference
+          %span
+            Reference:
+            %cite{title: project_ref}
+              = project_ref
+          = clipboard_button(clipboard_text: project_ref)
 
-  :javascript
-    new Subscription("#{toggle_subscription_path(issuable)}");
-    new IssuableContext();
\ No newline at end of file
+    :javascript
+      new Subscription("#{toggle_subscription_path(issuable)}");
+      new IssuableContext();
\ No newline at end of file
-- 
GitLab