diff options
author | Kamil Trzcinski <ayufan@ayufan.eu> | 2016-02-05 20:15:32 +0100 |
---|---|---|
committer | Kamil Trzcinski <ayufan@ayufan.eu> | 2016-02-05 20:15:32 +0100 |
commit | 170ca8435a6b881231476b372122cf7e5b028736 (patch) | |
tree | b3c762ef01268462b0b674b2d7f353e2a3a6cf48 /app | |
parent | a7c441aa17ba64eb702b583ac9198cdace599d2e (diff) | |
parent | 3a98279243e7a49a334c7eb6f806cd2b2072fbed (diff) | |
download | gitlab-ce-170ca8435a6b881231476b372122cf7e5b028736.tar.gz |
Merge branch 'master' into ci-permissions
# Conflicts:
# db/schema.rb
Diffstat (limited to 'app')
65 files changed, 736 insertions, 338 deletions
diff --git a/app/assets/javascripts/application.js.coffee b/app/assets/javascripts/application.js.coffee index d5e6ff0717a..367bd098bfd 100644 --- a/app/assets/javascripts/application.js.coffee +++ b/app/assets/javascripts/application.js.coffee @@ -211,8 +211,89 @@ $ -> $this.attr 'value', $this.val() return - $(document).on 'keyup', 'input[type="search"]' , (e) -> - $this = $(this) - $this.attr 'value', $this.val() - + $(document) + .off 'keyup', 'input[type="search"]' + .on 'keyup', 'input[type="search"]' , (e) -> + $this = $(this) + $this.attr 'value', $this.val() + + $(document) + .off 'breakpoint:change' + .on 'breakpoint:change', (e, breakpoint) -> + if breakpoint is 'sm' or breakpoint is 'xs' + $gutterIcon = $('.gutter-toggle').find('i') + if $gutterIcon.hasClass('fa-angle-double-right') + $gutterIcon.closest('a').trigger('click') + + $(document) + .off 'click', 'aside .gutter-toggle' + .on 'click', 'aside .gutter-toggle', (e) -> + e.preventDefault() + $this = $(this) + $thisIcon = $this.find 'i' + if $thisIcon.hasClass('fa-angle-double-right') + $thisIcon + .removeClass('fa-angle-double-right') + .addClass('fa-angle-double-left') + $this + .closest('aside') + .removeClass('right-sidebar-expanded') + .addClass('right-sidebar-collapsed') + $('.page-with-sidebar') + .removeClass('right-sidebar-expanded') + .addClass('right-sidebar-collapsed') + else + $thisIcon + .removeClass('fa-angle-double-left') + .addClass('fa-angle-double-right') + $this + .closest('aside') + .removeClass('right-sidebar-collapsed') + .addClass('right-sidebar-expanded') + $('.page-with-sidebar') + .removeClass('right-sidebar-collapsed') + .addClass('right-sidebar-expanded') + $.cookie("collapsed_gutter", + $('.right-sidebar') + .hasClass('right-sidebar-collapsed'), { path: '/' }) + + bootstrapBreakpoint = undefined; + checkBootstrapBreakpoints = -> + if $('.device-xs').is(':visible') + bootstrapBreakpoint = "xs" + else if $('.device-sm').is(':visible') + bootstrapBreakpoint = "sm" + else if $('.device-md').is(':visible') + bootstrapBreakpoint = "md" + else if $('.device-lg').is(':visible') + bootstrapBreakpoint = "lg" + + setBootstrapBreakpoints = -> + if $('.device-xs').length + return + + $("body") + .append('<div class="device-xs visible-xs"></div>'+ + '<div class="device-sm visible-sm"></div>'+ + '<div class="device-md visible-md"></div>'+ + '<div class="device-lg visible-lg"></div>') + checkBootstrapBreakpoints() + + fitSidebarForSize = -> + oldBootstrapBreakpoint = bootstrapBreakpoint + checkBootstrapBreakpoints() + if bootstrapBreakpoint != oldBootstrapBreakpoint + $(document).trigger('breakpoint:change', [bootstrapBreakpoint]) + + checkInitialSidebarSize = -> + if bootstrapBreakpoint is "xs" or "sm" + $(document).trigger('breakpoint:change', [bootstrapBreakpoint]) + + $(window) + .off "resize" + .on "resize", (e) -> + fitSidebarForSize() + + setBootstrapBreakpoints() + checkInitialSidebarSize() new Aside() diff --git a/app/assets/javascripts/dashboard.js.coffee b/app/assets/javascripts/dashboard.js.coffee index 00ee503ff16..dd295088312 100644 --- a/app/assets/javascripts/dashboard.js.coffee +++ b/app/assets/javascripts/dashboard.js.coffee @@ -1,3 +1,30 @@ -class @Dashboard - constructor: -> - new ProjectsList() +@Dashboard = + init: -> + this.initSearch() + + initSearch: -> + @timer = null + $("#project-filter-form-field").on('keyup', -> + clearTimeout(@timer) + @timer = setTimeout(Dashboard.filterResults, 500) + ) + + filterResults: => + $('.projects-list-holder').fadeTo(250, 0.5) + + form = null + form = $("#project-filter-form") + search = $("#project-filter-form-field").val() + project_filter_url = form.attr('action') + '?' + form.serialize() + + $.ajax + type: "GET" + url: form.attr('action') + data: form.serialize() + complete: -> + $('.projects-list-holder').fadeTo(250, 1) + success: (data) -> + $('div.projects-list-holder').replaceWith(data.html) + # Change url so if user reload a page - search results are saved + history.replaceState {page: project_filter_url}, document.title, project_filter_url + dataType: "json" diff --git a/app/assets/javascripts/dispatcher.js.coffee b/app/assets/javascripts/dispatcher.js.coffee index 2cdf01d874c..d4a2b74b143 100644 --- a/app/assets/javascripts/dispatcher.js.coffee +++ b/app/assets/javascripts/dispatcher.js.coffee @@ -58,7 +58,7 @@ class Dispatcher shortcut_handler = new ShortcutsNavigation() MergeRequests.init() when 'dashboard:show', 'root:show' - new Dashboard() + Dashboard.init() when 'dashboard:activity' new Activities() when 'dashboard:projects:starred' diff --git a/app/assets/javascripts/issuable_context.js.coffee b/app/assets/javascripts/issuable_context.js.coffee index 02232698bc2..d17b1123418 100644 --- a/app/assets/javascripts/issuable_context.js.coffee +++ b/app/assets/javascripts/issuable_context.js.coffee @@ -10,19 +10,7 @@ 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) -> + $(document).on "click",".edit-link", (e) -> block = $(@).parents('.block') block.find('.selectbox').show() block.find('.value').hide() diff --git a/app/assets/javascripts/projects_list.js.coffee b/app/assets/javascripts/projects_list.js.coffee index b71509dbc5a..ebf7140b7e3 100644 --- a/app/assets/javascripts/projects_list.js.coffee +++ b/app/assets/javascripts/projects_list.js.coffee @@ -22,5 +22,3 @@ class @ProjectsList else $(this).show() uiBox.find("ul.projects-list li.bottom").hide() - - diff --git a/app/assets/stylesheets/framework/avatar.scss b/app/assets/stylesheets/framework/avatar.scss index 36e582d4854..b7ffa3e6ffb 100644 --- a/app/assets/stylesheets/framework/avatar.scss +++ b/app/assets/stylesheets/framework/avatar.scss @@ -24,6 +24,7 @@ &.s26 { width: 26px; height: 26px; margin-right: 8px; } &.s32 { width: 32px; height: 32px; margin-right: 10px; } &.s36 { width: 36px; height: 36px; margin-right: 10px; } + &.s40 { width: 40px; height: 40px; margin-right: 10px; } &.s46 { width: 46px; height: 46px; margin-right: 15px; } &.s48 { width: 48px; height: 48px; margin-right: 10px; } &.s60 { width: 60px; height: 60px; margin-right: 12px; } @@ -40,7 +41,8 @@ &.s16 { font-size: 12px; line-height: 1.33; } &.s24 { font-size: 14px; line-height: 1.8; } &.s26 { font-size: 20px; line-height: 1.33; } - &.s32 { font-size: 22px; line-height: 32px; } + &.s32 { font-size: 20px; line-height: 32px; } + &.s40 { font-size: 16px; line-height: 40px; } &.s60 { font-size: 32px; line-height: 60px; } &.s90 { font-size: 36px; line-height: 90px; } &.s110 { font-size: 40px; line-height: 112px; font-weight: 300; } diff --git a/app/assets/stylesheets/framework/buttons.scss b/app/assets/stylesheets/framework/buttons.scss index 11df4c24056..5f193fa7434 100644 --- a/app/assets/stylesheets/framework/buttons.scss +++ b/app/assets/stylesheets/framework/buttons.scss @@ -2,7 +2,7 @@ @include border-radius(3px); font-size: $gl-font-size; font-weight: 500; - padding: $gl-vert-padding $gl-padding; + padding: $gl-vert-padding $gl-btn-padding; &:focus, &:active { diff --git a/app/assets/stylesheets/framework/issue_box.scss b/app/assets/stylesheets/framework/issue_box.scss index e93dbab0c42..08dcb563dce 100644 --- a/app/assets/stylesheets/framework/issue_box.scss +++ b/app/assets/stylesheets/framework/issue_box.scss @@ -9,7 +9,7 @@ display: block; float: left; - padding: 0 $gl-padding; + padding: 0 $gl-btn-padding; font-weight: normal; margin-right: 10px; font-size: $gl-font-size; diff --git a/app/assets/stylesheets/framework/lists.scss b/app/assets/stylesheets/framework/lists.scss index c6bc6fb324d..5c65383ec1a 100644 --- a/app/assets/stylesheets/framework/lists.scss +++ b/app/assets/stylesheets/framework/lists.scss @@ -109,7 +109,6 @@ ul.content-list { padding: 0; > li { - padding: $gl-padding 0; border-color: $table-border-color; color: $gl-gray; diff --git a/app/assets/stylesheets/framework/mobile.scss b/app/assets/stylesheets/framework/mobile.scss index 0997dfc287c..3bfac2ad9b5 100644 --- a/app/assets/stylesheets/framework/mobile.scss +++ b/app/assets/stylesheets/framework/mobile.scss @@ -116,7 +116,7 @@ display: none; } - aside { + aside:not(.right-sidebar){ display: none; } diff --git a/app/assets/stylesheets/framework/nav.scss b/app/assets/stylesheets/framework/nav.scss index e6c59f5a291..252a586358c 100644 --- a/app/assets/stylesheets/framework/nav.scss +++ b/app/assets/stylesheets/framework/nav.scss @@ -85,6 +85,10 @@ display: inline-block; } + > form { + display: inline-block; + } + input { height: 34px; display: inline-block; diff --git a/app/assets/stylesheets/framework/sidebar.scss b/app/assets/stylesheets/framework/sidebar.scss index 540d0b03163..b7f532c0771 100644 --- a/app/assets/stylesheets/framework/sidebar.scss +++ b/app/assets/stylesheets/framework/sidebar.scss @@ -200,6 +200,14 @@ } } +@mixin expanded-gutter { + padding-right: $gutter_width; +} + +@mixin collapsed-gutter { + padding-right: $sidebar_collapsed_width; +} + @mixin collapsed-sidebar { padding-left: $sidebar_collapsed_width; @@ -266,6 +274,7 @@ background: #f2f6f7; } +// page is small enough @media (max-width: $screen-md-max) { .page-sidebar-collapsed { @include collapsed-sidebar; @@ -275,12 +284,32 @@ @include collapsed-sidebar; } + .page-gutter { + &.right-sidebar-collapsed { + @include collapsed-gutter; + } + &.right-sidebar-expanded { + @include expanded-gutter; + } + } + .collapse-nav { display: none; } } +// page is large enough @media(min-width: $screen-md-max) { + + .page-gutter { + &.right-sidebar-collapsed { + @include collapsed-gutter; + } + &.right-sidebar-expanded { + @include expanded-gutter; + } + } + .page-sidebar-collapsed { @include collapsed-sidebar; } @@ -288,4 +317,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..efc3366e99c 100644 --- a/app/assets/stylesheets/framework/variables.scss +++ b/app/assets/stylesheets/framework/variables.scss @@ -12,6 +12,9 @@ $gl-font-size: 15px; $list-font-size: 15px; $sidebar_collapsed_width: 62px; $sidebar_width: 230px; +$gutter_collapsed_width: 62px; +$gutter_width: 312px; +$gutter_inner_width: 280px; $avatar_radius: 50%; $code_font_size: 13px; $code_line_height: 1.5; @@ -22,9 +25,10 @@ $header-height: 58px; $fixed-layout-width: 1280px; $gl-gray: #5a5a5a; $gl-padding: 16px; +$gl-btn-padding: 10px; $gl-vert-padding: 6px; $gl-padding-top:10px; -$gl-avatar-size: 46px; +$gl-avatar-size: 40px; $secondary-text: #7f8fa4; $error-exclamation-point: #E62958; @@ -36,11 +40,12 @@ $white-light: #FFFFFF; $white-normal: #ededed; $white-dark: #ededed; -$gray-light: #f7f7f7; -$gray-normal: #ededed; +$gray-light: #faf9f9; +$gray-normal: #f5f5f5; $gray-dark: #ededed; +$gray-darkest: #c9c9c9; -$green-light: #31AF64; +$green-light: #38ae67; $green-normal: #2FAA60; $green-dark: #2CA05B; @@ -52,7 +57,7 @@ $blue-medium-light: #3498CB; $blue-medium: #2F8EBF; $blue-medium-dark: #2D86B4; -$orange-light: #FC6443; +$orange-light: rgba(252, 109, 38, 0.80); $orange-normal: #E75E40; $orange-dark: #CE5237; @@ -64,8 +69,8 @@ $border-white-light: #F1F2F4; $border-white-normal: #D6DAE2; $border-white-dark: #C6CACF; -$border-gray-light: #d1d1d1; -$border-gray-normal: #D6DAE2; +$border-gray-light: rgba(0, 0, 0, 0.06); +$border-gray-normal: rgba(0, 0, 0, 0.10);; $border-gray-dark: #C6CACF; $border-green-light: #2FAA60; @@ -76,7 +81,7 @@ $border-blue-light: #2D9FD8; $border-blue-normal: #2897CE; $border-blue-dark: #258DC1; -$border-orange-light: #ED5C3D; +$border-orange-light: #fc6d26; $border-orange-normal: #CE5237; $border-orange-dark: #C14E35; diff --git a/app/assets/stylesheets/pages/dashboard.scss b/app/assets/stylesheets/pages/dashboard.scss index 25a86cd0f94..88639399148 100644 --- a/app/assets/stylesheets/pages/dashboard.scss +++ b/app/assets/stylesheets/pages/dashboard.scss @@ -40,10 +40,6 @@ .avatar { @include border-radius(50%); } - - .identicon { - line-height: 46px; - } } .dash-project-access-icon { diff --git a/app/assets/stylesheets/pages/events.scss b/app/assets/stylesheets/pages/events.scss index 8fa15b35748..35df9a61c86 100644 --- a/app/assets/stylesheets/pages/events.scss +++ b/app/assets/stylesheets/pages/events.scss @@ -4,7 +4,7 @@ */ .event-item { font-size: $gl-font-size; - padding: $gl-padding 0 $gl-padding ($gl-avatar-size + 15px); + padding: $gl-padding-top 0 $gl-padding-top ($gl-avatar-size + $gl-padding-top); border-bottom: 1px solid $table-border-color; color: #7f8fa4; @@ -16,7 +16,7 @@ .event-title, .event-item-timestamp { - line-height: 44px; + line-height: 40px; } } @@ -25,7 +25,7 @@ } .avatar { - margin-left: -($gl-avatar-size + 15px); + margin-left: -($gl-avatar-size + $gl-padding-top); } .event-title { @@ -41,7 +41,6 @@ margin-right: 174px; .event-note { - margin-top: 5px; word-wrap: break-word; .md { @@ -98,8 +97,6 @@ &:last-child { border:none } .event_commits { - margin-top: 9px; - li { &.commit { background: transparent; diff --git a/app/assets/stylesheets/pages/issuable.scss b/app/assets/stylesheets/pages/issuable.scss index 977ada0ff38..9d5dc42b6cc 100644 --- a/app/assets/stylesheets/pages/issuable.scss +++ b/app/assets/stylesheets/pages/issuable.scss @@ -29,21 +29,8 @@ } } -.project-issuable-filter { - .controls { - float: right; - margin-top: 11px; - } - - .nav-links { - text-align: left; - } -} - .issuable-details { section { - border-right: 1px solid $border-white-light; - .issuable-discussion { margin-right: 1px; } @@ -73,11 +60,35 @@ .block { @include clearfix; padding: $gl-padding 0; - border-bottom: 1px solid #F0F0F0; + border-bottom: 1px solid $border-gray-light; + // This prevents the mess when resizing the sidebar + // of elements repositioning themselves.. + width: $gutter_inner_width; + overflow-x: hidden; + // -- + + &:first-child { + padding-top: 5px; + } &:last-child { border: none; } + + span { + margin-top: 7px; + display: inline-block; + } + + .issuable-count { + + } + + .gutter-toggle { + margin-left: 20px; + border-left: 1px solid $border-gray-light; + padding-left: 10px; + } } .title { @@ -133,3 +144,98 @@ margin-right: 2px; } } + + +.right-sidebar { + position: fixed; + top: 58px; + right: 0; + height: 100%; + transition-duration: .3s; + background: $gray-light; + overflow: scroll; + padding: 10px 20px; + + &.right-sidebar-expanded { + width: $gutter_width; + + hr { + display: none; + } + } + + .subscribe-button { + span { + margin-top: 0; + } + } + + &.right-sidebar-collapsed { + width: $sidebar_collapsed_width; + padding-top: 0; + overflow-x: hidden; + + hr { + margin: 0; + color: $gray-normal; + border-color: $gray-normal; + width: 62px; + margin-left: -20px + } + + .block { + border-bottom: none; + padding: 15px 0 0 0; + } + } + + .btn { + background: $gray-normal; + border: 1px solid $border-gray-normal; + } + + &.right-sidebar-collapsed { + .issuable-count, + .issuable-nav, + .assignee > *, + .milestone > *, + .labels > *, + .participants > *, + .light > *, + .project-reference > * { + display: none; + } + + .gutter-toggle { + margin-left: -$gutter_inner_width + 4; + } + + .sidebar-collapsed-icon { + display: block; + float: left; + width: 62px; + text-align: center; + margin-left: -19px; + padding-bottom: 10px; + color: #999999; + + span { + display: block; + margin-top: 0; + } + } + + } + + &.right-sidebar-expanded { + .sidebar-collapsed-icon { + display: none; + } + } +} + +.detail-page-description { + small { + color: $gray-darkest; + } +}
\ No newline at end of file diff --git a/app/assets/stylesheets/pages/issues.scss b/app/assets/stylesheets/pages/issues.scss index dd6a251f811..8694bd654a7 100644 --- a/app/assets/stylesheets/pages/issues.scss +++ b/app/assets/stylesheets/pages/issues.scss @@ -65,10 +65,6 @@ form.edit-issue { width: 3em; } -.merge-request-info { - padding-left: 5px; -} - .merge-request-status { color: $gl-gray; font-size: 15px; @@ -143,4 +139,4 @@ form.edit-issue { .issue-closed-by-widget { color: $secondary-text; margin-left: 52px; -}
\ No newline at end of file +} diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss index dd4ff39c5b8..046bae672fc 100644 --- a/app/assets/stylesheets/pages/projects.scss +++ b/app/assets/stylesheets/pages/projects.scss @@ -391,12 +391,11 @@ pre.light-well { @include basic-list; .project-row { - padding: $gl-padding 0; border-color: $table-border-color; &.no-description { .project { - line-height: 44px; + line-height: 40px; } } @@ -409,7 +408,7 @@ pre.light-well { .project-controls { float: right; color: $gl-gray; - line-height: 45px; + line-height: 40px; color: #7f8fa4; a:hover { diff --git a/app/controllers/admin/broadcast_messages_controller.rb b/app/controllers/admin/broadcast_messages_controller.rb index 4735b27c65d..a470d865408 100644 --- a/app/controllers/admin/broadcast_messages_controller.rb +++ b/app/controllers/admin/broadcast_messages_controller.rb @@ -2,7 +2,7 @@ class Admin::BroadcastMessagesController < Admin::ApplicationController before_action :finder, only: [:edit, :update, :destroy] def index - @broadcast_messages = BroadcastMessage.reorder("starts_at ASC").page(params[:page]) + @broadcast_messages = BroadcastMessage.reorder("ends_at DESC").page(params[:page]) @broadcast_message = BroadcastMessage.new end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 7fa2f68ef07..48b1f95acb9 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -277,9 +277,10 @@ class ApplicationController < ActionController::Base } end - def view_to_html_string(partial) + def view_to_html_string(partial, locals = {}) render_to_string( partial, + locals: locals, layout: false, formats: [:html] ) diff --git a/app/controllers/dashboard/projects_controller.rb b/app/controllers/dashboard/projects_controller.rb index 721e2a6bcbd..0bcc78a8bc7 100644 --- a/app/controllers/dashboard/projects_controller.rb +++ b/app/controllers/dashboard/projects_controller.rb @@ -5,6 +5,14 @@ class Dashboard::ProjectsController < Dashboard::ApplicationController @projects = current_user.authorized_projects.sorted_by_activity.non_archived @projects = @projects.sort(@sort = params[:sort]) @projects = @projects.includes(:namespace) + + terms = params['filter_projects'] + + if terms.present? + @projects = @projects.search(terms) + end + + @projects = @projects.page(params[:page]).per(PER_PAGE) @last_push = current_user.recent_push respond_to do |format| @@ -14,6 +22,11 @@ class Dashboard::ProjectsController < Dashboard::ApplicationController load_events render layout: false end + format.json do + render json: { + html: view_to_html_string("dashboard/projects/_projects", locals: { projects: @projects }) + } + end end end @@ -21,6 +34,14 @@ class Dashboard::ProjectsController < Dashboard::ApplicationController @projects = current_user.starred_projects @projects = @projects.includes(:namespace, :forked_from_project, :tags) @projects = @projects.sort(@sort = params[:sort]) + + terms = params['filter_projects'] + + if terms.present? + @projects = @projects.search(terms) + end + + @projects = @projects.page(params[:page]).per(PER_PAGE) @last_push = current_user.recent_push @groups = [] @@ -28,8 +49,9 @@ class Dashboard::ProjectsController < Dashboard::ApplicationController format.html format.json do - load_events - pager_json("events/_events", @events.count) + render json: { + html: view_to_html_string("dashboard/projects/_projects", locals: { projects: @projects }) + } end end end diff --git a/app/controllers/explore/projects_controller.rb b/app/controllers/explore/projects_controller.rb index a5aeaed66c5..2689bf4f1ec 100644 --- a/app/controllers/explore/projects_controller.rb +++ b/app/controllers/explore/projects_controller.rb @@ -11,14 +11,14 @@ class Explore::ProjectsController < Explore::ApplicationController end def trending - @trending_projects = TrendingProjectsFinder.new.execute(current_user) - @trending_projects = @trending_projects.non_archived - @trending_projects = @trending_projects.page(params[:page]).per(PER_PAGE) + @projects = TrendingProjectsFinder.new.execute(current_user) + @projects = @projects.non_archived + @projects = @projects.page(params[:page]).per(PER_PAGE) end def starred - @starred_projects = ProjectsFinder.new.execute(current_user) - @starred_projects = @starred_projects.reorder('star_count DESC') - @starred_projects = @starred_projects.page(params[:page]).per(PER_PAGE) + @projects = ProjectsFinder.new.execute(current_user) + @projects = @projects.reorder('star_count DESC') + @projects = @projects.page(params[:page]).per(PER_PAGE) end end diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb index ad6b3eae932..90475c17c17 100644 --- a/app/controllers/groups_controller.rb +++ b/app/controllers/groups_controller.rb @@ -41,6 +41,7 @@ class GroupsController < Groups::ApplicationController def show @last_push = current_user.recent_push if current_user @projects = @projects.includes(:namespace) + @projects = @projects.page(params[:page]).per(PER_PAGE) respond_to do |format| format.html diff --git a/app/controllers/omniauth_callbacks_controller.rb b/app/controllers/omniauth_callbacks_controller.rb index 4c13228fce9..9cf76521a0d 100644 --- a/app/controllers/omniauth_callbacks_controller.rb +++ b/app/controllers/omniauth_callbacks_controller.rb @@ -1,4 +1,5 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController + include AuthenticatesWithTwoFactor protect_from_forgery except: [:kerberos, :saml, :cas3] @@ -29,8 +30,12 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController # Do additional LDAP checks for the user filter and EE features if ldap_user.allowed? - log_audit_event(@user, with: :ldap) - sign_in_and_redirect(@user) + if @user.two_factor_enabled? + prompt_for_two_factor(@user) + else + log_audit_event(@user, with: :ldap) + sign_in_and_redirect(@user) + end else flash[:alert] = "Access denied for your LDAP account." redirect_to new_user_session_path diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 280228dbcc0..6055b606086 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -4,8 +4,9 @@ class UsersController < ApplicationController def show @contributed_projects = contributed_projects.joined(@user).reject(&:forked?) - + @projects = PersonalProjectsFinder.new(@user).execute(current_user) + @projects = @projects.page(params[:page]).per(PER_PAGE) @groups = @user.groups.order_id_desc diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index a2458ad3be0..622cbfe3cc4 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -169,18 +169,6 @@ module ApplicationHelper Gitlab.config.extra end - def search_placeholder - if @project && @project.persisted? - 'Search' - elsif @snippet || @snippets || @show_snippets - 'Search snippets' - elsif @group && @group.persisted? - 'Search in this group' - else - 'Search' - end - end - # Render a `time` element with Javascript-based relative date and tooltip # # time - Time object @@ -293,6 +281,76 @@ module ApplicationHelper end end + def issuable_link_next(project,issuable) + if project.nil? + nil + elsif current_controller?(:issues) + namespace_project_issue_path(project.namespace, project, next_issuable_for(project, issuable.id).try(:iid)) + elsif current_controller?(:merge_requests) + namespace_project_merge_request_path(project.namespace, project, next_issuable_for(project, issuable.id).try(:iid)) + end + end + + def issuable_link_prev(project,issuable) + if project.nil? + nil + elsif current_controller?(:issues) + namespace_project_issue_path(project.namespace, project, prev_issuable_for(project, issuable.id).try(:iid)) + elsif current_controller?(:merge_requests) + namespace_project_merge_request_path(project.namespace, project, prev_issuable_for(project, issuable.id).try(:iid)) + 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, id) + 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 has_next_issuable?(project, id) + 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 prev_issuable_for(project, id) + 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 has_prev_issuable?(project, id) + 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 state_filters_text_for(entity, project) titles = { opened: "Open" diff --git a/app/helpers/labels_helper.rb b/app/helpers/labels_helper.rb index 92eac0560bd..1c7fcc13b42 100644 --- a/app/helpers/labels_helper.rb +++ b/app/helpers/labels_helper.rb @@ -7,6 +7,8 @@ module LabelsHelper # project - Project object which will be used as the context for the label's # link. If omitted, defaults to `@project`, or the label's own # project. + # type - The type of item the link will point to (:issue or + # :merge_request). If omitted, defaults to :issue. # block - An optional block that will be passed to `link_to`, forming the # body of the link element. If omitted, defaults to # `render_colored_label`. @@ -23,14 +25,19 @@ module LabelsHelper # # Force the generated link to use a provided project # link_to_label(label, project: Project.last) # + # # Force the generated link to point to merge requests instead of issues + # link_to_label(label, type: :merge_request) + # # # Customize link body with a block # link_to_label(label) { "My Custom Label Text" } # # Returns a String - def link_to_label(label, project: nil, &block) + def link_to_label(label, project: nil, type: :issue, &block) project ||= @project || label.project - link = namespace_project_issues_path(project.namespace, project, - label_name: label.name) + link = send("namespace_project_#{type.to_s.pluralize}_path", + project.namespace, + project, + label_name: label.name) if block_given? link_to link, &block diff --git a/app/helpers/nav_helper.rb b/app/helpers/nav_helper.rb index e6fb8670e57..2c299d1d794 100644 --- a/app/helpers/nav_helper.rb +++ b/app/helpers/nav_helper.rb @@ -3,6 +3,18 @@ module NavHelper cookies[:collapsed_nav] == 'true' end + def sidebar_gutter_collapsed_class + if cookies[:collapsed_gutter] == 'true' + "right-sidebar-collapsed" + else + "right-sidebar-expanded" + end + end + + def sidebar_gutter_collapsed? + cookies[:collapsed_gutter] == 'true' + end + def nav_sidebar_class if nav_menu_collapsed? "sidebar-collapsed" @@ -19,6 +31,17 @@ module NavHelper end end + def page_gutter_class + + if current_path?('merge_requests#show') || current_path?('issues#show') + if cookies[:collapsed_gutter] == 'true' + "page-gutter right-sidebar-collapsed" + else + "page-gutter right-sidebar-expanded" + end + end + end + def nav_header_class if nav_menu_collapsed? "header-collapsed" diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index 6b5fad1963a..dff83f09ca4 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -20,6 +20,12 @@ module ProjectsHelper end end + def link_to_member_avatar(author, opts = {}) + default_opts = { avatar: true, name: true, size: 16, author_class: 'author', title: ":name" } + opts = default_opts.merge(opts) + image_tag(avatar_icon(author, opts[:size]), width: opts[:size], class: "avatar avatar-inline #{"s#{opts[:size]}" if opts[:size]}", alt:'') if opts[:avatar] + end + def link_to_member(project, author, opts = {}) default_opts = { avatar: true, name: true, size: 16, author_class: 'author', title: ":name" } opts = default_opts.merge(opts) diff --git a/app/models/event.rb b/app/models/event.rb index 4be23a1cf72..9a0bbf50f8b 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -49,7 +49,7 @@ class Event < ActiveRecord::Base scope :code_push, -> { where(action: PUSHED) } scope :in_projects, ->(projects) do - where(project_id: projects.select(:id).reorder(nil)).recent + where(project_id: projects.map(&:id)).recent end scope :with_associations, -> { includes(project: :namespace) } diff --git a/app/views/admin/broadcast_messages/index.html.haml b/app/views/admin/broadcast_messages/index.html.haml index 49e33698b63..c05538a393c 100644 --- a/app/views/admin/broadcast_messages/index.html.haml +++ b/app/views/admin/broadcast_messages/index.html.haml @@ -34,4 +34,4 @@ = link_to icon('pencil-square-o'), edit_admin_broadcast_message_path(message), title: 'Edit', class: 'btn btn-xs' = link_to icon('times'), admin_broadcast_message_path(message), method: :delete, remote: true, title: 'Remove', class: 'js-remove-tr btn btn-xs btn-danger' - = paginate @broadcast_messages + = paginate @broadcast_messages, theme: 'gitlab' diff --git a/app/views/admin/builds/index.html.haml b/app/views/admin/builds/index.html.haml index ebf2b7b60e7..5931efdefe6 100644 --- a/app/views/admin/builds/index.html.haml +++ b/app/views/admin/builds/index.html.haml @@ -1,9 +1,4 @@ -.project-issuable-filter - .controls - .pull-left.hidden-xs - - if @all_builds.running_or_pending.any? - = link_to 'Cancel all', cancel_all_admin_builds_path, data: { confirm: 'Are you sure?' }, class: 'btn btn-danger', method: :post - +.top-area %ul.nav-links %li{class: ('active' if @scope.nil?)} = link_to admin_builds_path do @@ -20,7 +15,11 @@ Finished %span.badge.js-running-count= number_with_delimiter(@all_builds.finished.count(:id)) -.gray-content-block + .nav-controls + - if @all_builds.running_or_pending.any? + = link_to 'Cancel all', cancel_all_admin_builds_path, data: { confirm: 'Are you sure?' }, class: 'btn btn-danger', method: :post + +.gray-content-block.second-block #{(@scope || 'running').capitalize} builds %ul.content-list diff --git a/app/views/admin/dashboard/index.html.haml b/app/views/admin/dashboard/index.html.haml index cc389c3ae08..3274ba5377b 100644 --- a/app/views/admin/dashboard/index.html.haml +++ b/app/views/admin/dashboard/index.html.haml @@ -92,6 +92,11 @@ Rails %span.pull-right #{Rails::VERSION::STRING} + + %p + = Gitlab::Database.adapter_name + %span.pull-right + = Gitlab::Database.version %hr .row .col-sm-4 diff --git a/app/views/dashboard/_projects_head.html.haml b/app/views/dashboard/_projects_head.html.haml index d865a2c6fae..d46998ec1e9 100644 --- a/app/views/dashboard/_projects_head.html.haml +++ b/app/views/dashboard/_projects_head.html.haml @@ -13,7 +13,8 @@ Explore Projects .nav-controls - = search_field_tag :filter_projects, nil, placeholder: 'Filter by name...', class: 'projects-list-filter form-control hidden-xs input-short', spellcheck: false + = form_tag request.original_url, method: :get, class: 'project-filter-form', id: 'project-filter-form' do |f| + = search_field_tag :filter_projects, params[:filter_projects], placeholder: 'Filter by name...', class: 'project-filter-form-field form-control input-short', spellcheck: false, id: 'project-filter-form-field' = render 'explore/projects/dropdown' - if current_user.can_create_project? = link_to new_project_path, class: 'btn btn-new' do diff --git a/app/views/dashboard/issues.html.haml b/app/views/dashboard/issues.html.haml index f363f035974..dfa5f80eef8 100644 --- a/app/views/dashboard/issues.html.haml +++ b/app/views/dashboard/issues.html.haml @@ -4,17 +4,15 @@ - if current_user = auto_discovery_link_tag(:atom, issues_dashboard_url(format: :atom, private_token: current_user.private_token), title: "#{current_user.name} issues") -.project-issuable-filter - .controls - .pull-left - - if current_user - .hidden-xs.pull-left - = link_to issues_dashboard_url(format: :atom, private_token: current_user.private_token), class: 'btn' do - %i.fa.fa-rss - +.top-area + = render 'shared/issuable/nav', type: :issues + .nav-controls + - if current_user + = link_to issues_dashboard_url(format: :atom, private_token: current_user.private_token), class: 'btn' do + = icon('rss') = render 'shared/new_project_item_select', path: 'issues/new', label: "New Issue" - = render 'shared/issuable/filter', type: :issues += render 'shared/issuable/filter', type: :issues .prepend-top-default = render 'shared/issues' diff --git a/app/views/dashboard/merge_requests.html.haml b/app/views/dashboard/merge_requests.html.haml index bbe4cc1f824..fb016599fef 100644 --- a/app/views/dashboard/merge_requests.html.haml +++ b/app/views/dashboard/merge_requests.html.haml @@ -1,11 +1,12 @@ - page_title "Merge Requests" - header_title "Merge Requests", merge_requests_dashboard_path(assignee_id: current_user.id) -.project-issuable-filter - .controls +.top-area + = render 'shared/issuable/nav', type: :merge_requests + .nav-controls = render 'shared/new_project_item_select', path: 'merge_requests/new', label: "New Merge Request" - = render 'shared/issuable/filter', type: :merge_requests += render 'shared/issuable/filter', type: :merge_requests .prepend-top-default = render 'shared/merge_requests' diff --git a/app/views/dashboard/projects/_projects.html.haml b/app/views/dashboard/projects/_projects.html.haml index cea9ffcc748..933a3edd0f0 100644 --- a/app/views/dashboard/projects/_projects.html.haml +++ b/app/views/dashboard/projects/_projects.html.haml @@ -1,3 +1,6 @@ .projects-list-holder = render 'shared/projects/list', projects: @projects, ci: true + + :javascript + Dashboard.init() diff --git a/app/views/events/_event.html.haml b/app/views/events/_event.html.haml index 46432a92348..36fb2d51629 100644 --- a/app/views/events/_event.html.haml +++ b/app/views/events/_event.html.haml @@ -3,8 +3,8 @@ .event-item-timestamp #{time_ago_with_tooltip(event.created_at)} - = cache [event, current_application_settings, "v2.1"] do - = image_tag avatar_icon(event.author_email, 46), class: "avatar s46", alt:'' + = cache [event, current_application_settings, "v2.2"] do + = image_tag avatar_icon(event.author_email, 40), class: "avatar s40", alt:'' - if event.created_project? = render "events/event/created_project", event: event - elsif event.push? diff --git a/app/views/explore/projects/index.html.haml b/app/views/explore/projects/index.html.haml index bee8518d57a..dca75498573 100644 --- a/app/views/explore/projects/index.html.haml +++ b/app/views/explore/projects/index.html.haml @@ -13,4 +13,3 @@ = render 'filter' = render 'projects', projects: @projects -= paginate @projects, theme: "gitlab" diff --git a/app/views/explore/projects/starred.html.haml b/app/views/explore/projects/starred.html.haml index 16f52f7a530..ec461755103 100644 --- a/app/views/explore/projects/starred.html.haml +++ b/app/views/explore/projects/starred.html.haml @@ -7,5 +7,4 @@ = render 'explore/head' = render 'explore/projects/nav' -= render 'projects', projects: @starred_projects -= paginate @starred_projects, theme: 'gitlab' += render 'projects', projects: @projects diff --git a/app/views/explore/projects/trending.html.haml b/app/views/explore/projects/trending.html.haml index adcda810061..ec461755103 100644 --- a/app/views/explore/projects/trending.html.haml +++ b/app/views/explore/projects/trending.html.haml @@ -7,4 +7,4 @@ = render 'explore/head' = render 'explore/projects/nav' -= render 'projects', projects: @trending_projects += render 'projects', projects: @projects diff --git a/app/views/groups/issues.html.haml b/app/views/groups/issues.html.haml index 90ade1e1680..b0805593fdc 100644 --- a/app/views/groups/issues.html.haml +++ b/app/views/groups/issues.html.haml @@ -4,17 +4,15 @@ - if current_user = auto_discovery_link_tag(:atom, issues_group_url(@group, format: :atom, private_token: current_user.private_token), title: "#{@group.name} issues") -.project-issuable-filter - .controls - .pull-left - - if current_user - .hidden-xs.pull-left - = link_to issues_group_url(@group, format: :atom, private_token: current_user.private_token), class: 'btn' do - %i.fa.fa-rss - +.top-area + = render 'shared/issuable/nav', type: :issues + .nav-controls + - if current_user + = link_to issues_group_url(@group, format: :atom, private_token: current_user.private_token), class: 'btn' do + = icon('rss') = render 'shared/new_project_item_select', path: 'issues/new', label: "New Issue" - = render 'shared/issuable/filter', type: :issues += render 'shared/issuable/filter', type: :issues .gray-content-block.second-block Only issues from diff --git a/app/views/groups/merge_requests.html.haml b/app/views/groups/merge_requests.html.haml index f662f5a8c17..e1c9dd931ee 100644 --- a/app/views/groups/merge_requests.html.haml +++ b/app/views/groups/merge_requests.html.haml @@ -1,11 +1,12 @@ - page_title "Merge Requests" - header_title group_title(@group, "Merge Requests", merge_requests_group_path(@group)) -.project-issuable-filter - .controls +.top-area + = render 'shared/issuable/nav', type: :merge_requests + .nav-controls = render 'shared/new_project_item_select', path: 'merge_requests/new', label: "New Merge Request" - = render 'shared/issuable/filter', type: :merge_requests += render 'shared/issuable/filter', type: :merge_requests .gray-content-block.second-block Only merge requests from diff --git a/app/views/help/_shortcuts.html.haml b/app/views/help/_shortcuts.html.haml index 9ee6f07b26b..8e982718d23 100644 --- a/app/views/help/_shortcuts.html.haml +++ b/app/views/help/_shortcuts.html.haml @@ -40,10 +40,6 @@ %td.shortcut .key enter %td Open Selection - %tr - %td.shortcut - .key t - %td Go to finding file %tbody %tr %th @@ -161,6 +157,10 @@ .key s %td Go to snippets + %tr + %td.shortcut + .key t + %td Go to finding file .col-lg-4 %table.shortcut-mappings %tbody{ class: 'hidden-shortcut network', style: 'display:none' } 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/layouts/_search.html.haml b/app/views/layouts/_search.html.haml index a44f5762a6b..20042e21bf2 100644 --- a/app/views/layouts/_search.html.haml +++ b/app/views/layouts/_search.html.haml @@ -1,6 +1,6 @@ .search = form_tag search_path, method: :get, class: 'navbar-form pull-left' do |f| - = search_field_tag "search", nil, placeholder: search_placeholder, class: "search-input form-control", spellcheck: false + = search_field_tag "search", nil, placeholder: 'Search', class: "search-input form-control", spellcheck: false = hidden_field_tag :group_id, @group.try(:id) - if @project && @project.persisted? = hidden_field_tag :project_id, @project.id diff --git a/app/views/profiles/accounts/show.html.haml b/app/views/profiles/accounts/show.html.haml index 52bfc595fda..9fa96084f94 100644 --- a/app/views/profiles/accounts/show.html.haml +++ b/app/views/profiles/accounts/show.html.haml @@ -31,34 +31,33 @@ - else = f.submit 'Generate', class: "btn btn-default" - - unless current_user.ldap_user? - .panel.panel-default - .panel-heading - Two-factor Authentication - .panel-body - - if current_user.two_factor_enabled? - .pull-right - = link_to 'Disable Two-factor Authentication', profile_two_factor_auth_path, method: :delete, class: 'btn btn-close btn-sm', - data: { confirm: 'Are you sure?' } - %p.text-success - %strong - Two-factor Authentication is enabled - %p - If you lose your recovery codes you can - %strong - = succeed ',' do - = link_to 'generate new ones', codes_profile_two_factor_auth_path, method: :post, data: { confirm: 'Are you sure?' } - invalidating all previous codes. + .panel.panel-default + .panel-heading + Two-factor Authentication + .panel-body + - if current_user.two_factor_enabled? + .pull-right + = link_to 'Disable Two-factor Authentication', profile_two_factor_auth_path, method: :delete, class: 'btn btn-close btn-sm', + data: { confirm: 'Are you sure?' } + %p.text-success + %strong + Two-factor Authentication is enabled + %p + If you lose your recovery codes you can + %strong + = succeed ',' do + = link_to 'generate new ones', codes_profile_two_factor_auth_path, method: :post, data: { confirm: 'Are you sure?' } + invalidating all previous codes. - - else - %p - Increase your account's security by enabling two-factor authentication (2FA). - %p - Each time you log in you’ll be required to provide your username and - password as usual, plus a randomly-generated code from your phone. + - else + %p + Increase your account's security by enabling two-factor authentication (2FA). + %p + Each time you log in you’ll be required to provide your username and + password as usual, plus a randomly-generated code from your phone. - .form-actions - = link_to 'Enable Two-factor Authentication', new_profile_two_factor_auth_path, class: 'btn btn-success' + .form-actions + = link_to 'Enable Two-factor Authentication', new_profile_two_factor_auth_path, class: 'btn btn-success' - if button_based_providers.any? .panel.panel-default diff --git a/app/views/projects/issues/index.html.haml b/app/views/projects/issues/index.html.haml index d6260ab2900..fde9304c0f8 100644 --- a/app/views/projects/issues/index.html.haml +++ b/app/views/projects/issues/index.html.haml @@ -5,22 +5,19 @@ - if current_user = auto_discovery_link_tag(:atom, namespace_project_issues_url(@project.namespace, @project, :atom, private_token: current_user.private_token), title: "#{@project.name} issues") -.project-issuable-filter - .controls - .pull-left - - if current_user - .hidden-xs.pull-left - = link_to namespace_project_issues_path(@project.namespace, @project, :atom, { private_token: current_user.private_token }), class: 'btn append-right-10' do - %i.fa.fa-rss - +.top-area + = render 'shared/issuable/nav', type: :issues + .nav-controls + - if current_user + = link_to namespace_project_issues_path(@project.namespace, @project, :atom, { private_token: current_user.private_token }), class: 'btn append-right-10' do + = icon('rss') = render 'shared/issuable/search_form', path: namespace_project_issues_path(@project.namespace, @project) - - if can? current_user, :create_issue, @project - = link_to new_namespace_project_issue_path(@project.namespace, @project, issue: { assignee_id: @issuable_finder.assignee.try(:id), milestone_id: @issuable_finder.milestones.try(:first).try(:id) }), class: "btn btn-new pull-left", title: "New Issue", id: "new_issue_link" do - %i.fa.fa-plus + = link_to new_namespace_project_issue_path(@project.namespace, @project, issue: { assignee_id: @issuable_finder.assignee.try(:id), milestone_id: @issuable_finder.milestones.try(:first).try(:id) }), class: "btn btn-new", title: "New Issue", id: "new_issue_link" do + = icon('plus') New Issue - = render 'shared/issuable/filter', type: :issues += render 'shared/issuable/filter', type: :issues .issues-holder = render "issues" diff --git a/app/views/projects/issues/show.html.haml b/app/views/projects/issues/show.html.haml index 51dcca7a1ab..121c775560f 100644 --- a/app/views/projects/issues/show.html.haml +++ b/app/views/projects/issues/show.html.haml @@ -15,11 +15,6 @@ opened by #{link_to_member(@project, @issue.author, size: 24)} · = time_ago_with_tooltip(@issue.created_at, placement: 'bottom', html_class: 'issue_created_ago') - - if @issue.updated_at != @issue.created_at - %span - · - = icon('edit', title: 'edited') - = time_ago_with_tooltip(@issue.updated_at, placement: 'bottom', html_class: 'issue_edited_ago') .pull-right - if can?(current_user, :create_issue, @project) @@ -46,6 +41,10 @@ = markdown(@issue.description, cache_key: [@issue, "description"]) %textarea.hidden.js-task-list-field = @issue.description + - if @issue.updated_at != @issue.created_at + %small + Edited + = time_ago_with_tooltip(@issue.updated_at, placement: 'bottom', html_class: 'issue_edited_ago') .merge-requests = render 'merge_requests' @@ -54,11 +53,8 @@ = 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/issues/update.js.haml b/app/views/projects/issues/update.js.haml index 2f0f3fcfb06..a54733883b4 100644 --- a/app/views/projects/issues/update.js.haml +++ b/app/views/projects/issues/update.js.haml @@ -1,3 +1,3 @@ -$('.issuable-sidebar').html("#{escape_javascript(render 'shared/issuable/sidebar', issuable: @issue)}"); -$('.issuable-sidebar').parent().effect('highlight') -new Issue(); +$('aside.right-sidebar')[0].outerHTML = "#{escape_javascript(render 'shared/issuable/sidebar', issuable: @issue)}"; +$('aside.right-sidebar').effect('highlight'); +new Issue();
\ No newline at end of file diff --git a/app/views/projects/merge_requests/_merge_request.html.haml b/app/views/projects/merge_requests/_merge_request.html.haml index a051729dc32..e25bf917b43 100644 --- a/app/views/projects/merge_requests/_merge_request.html.haml +++ b/app/views/projects/merge_requests/_merge_request.html.haml @@ -53,7 +53,7 @@ - if merge_request.labels.any? - merge_request.labels.each do |label| - = link_to_label(label, project: merge_request.project) + = link_to_label(label, project: merge_request.project, type: 'merge_request') - if merge_request.tasks? %span.task-status diff --git a/app/views/projects/merge_requests/_show.html.haml b/app/views/projects/merge_requests/_show.html.haml index 8641c3d8b4b..da67645bc2b 100644 --- a/app/views/projects/merge_requests/_show.html.haml +++ b/app/views/projects/merge_requests/_show.html.haml @@ -70,12 +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 - # This tab is always loaded via AJAX @@ -87,6 +84,8 @@ .mr-loading-status = spinner += render 'shared/issuable/sidebar', issuable: @merge_request + :javascript var merge_request; diff --git a/app/views/projects/merge_requests/index.html.haml b/app/views/projects/merge_requests/index.html.haml index 8d5d0394a82..e56a44e0a79 100644 --- a/app/views/projects/merge_requests/index.html.haml +++ b/app/views/projects/merge_requests/index.html.haml @@ -2,16 +2,19 @@ = render "header_title" = render 'projects/last_push' -.project-issuable-filter - .controls + +.top-area + = render 'shared/issuable/nav', type: :merge_requests + .nav-controls = render 'shared/issuable/search_form', path: namespace_project_merge_requests_path(@project.namespace, @project) - merge_project = can?(current_user, :create_merge_request, @project) ? @project : (current_user && current_user.fork_of(@project)) - if merge_project - .pull-left.hidden-xs - = link_to new_namespace_project_merge_request_path(merge_project.namespace, merge_project), class: "btn btn-new", title: "New Merge Request" do - %i.fa.fa-plus - New Merge Request - = render 'shared/issuable/filter', type: :merge_requests + = link_to new_namespace_project_merge_request_path(merge_project.namespace, merge_project), class: "btn btn-new", title: "New Merge Request" do + = icon('plus') + New Merge Request + += render 'shared/issuable/filter', type: :merge_requests + .merge-requests-holder = render 'merge_requests' diff --git a/app/views/projects/merge_requests/show/_mr_box.html.haml b/app/views/projects/merge_requests/show/_mr_box.html.haml index 905823f79d9..602f787e6cf 100644 --- a/app/views/projects/merge_requests/show/_mr_box.html.haml +++ b/app/views/projects/merge_requests/show/_mr_box.html.haml @@ -10,3 +10,8 @@ = markdown(@merge_request.description, cache_key: [@merge_request, "description"]) %textarea.hidden.js-task-list-field = @merge_request.description + + - if @merge_request.updated_at != @merge_request.created_at + %small + Edited + = time_ago_with_tooltip(@merge_request.updated_at, placement: 'bottom') diff --git a/app/views/projects/merge_requests/show/_mr_title.html.haml b/app/views/projects/merge_requests/show/_mr_title.html.haml index fc6fb2a0d42..473fbff721b 100644 --- a/app/views/projects/merge_requests/show/_mr_title.html.haml +++ b/app/views/projects/merge_requests/show/_mr_title.html.haml @@ -8,11 +8,6 @@ opened by #{link_to_member(@project, @merge_request.author, size: 24)} · = time_ago_with_tooltip(@merge_request.created_at) - - if @merge_request.updated_at != @merge_request.created_at - %span - · - = icon('edit', title: 'edited') - = time_ago_with_tooltip(@merge_request.updated_at, placement: 'bottom') .issue-btn-group.pull-right - if can?(current_user, :update_merge_request, @merge_request) diff --git a/app/views/projects/merge_requests/update.js.haml b/app/views/projects/merge_requests/update.js.haml index 93db65ddf79..ce5157d69a2 100644 --- a/app/views/projects/merge_requests/update.js.haml +++ b/app/views/projects/merge_requests/update.js.haml @@ -1,3 +1,3 @@ -$('.issuable-sidebar').html("#{escape_javascript(render 'shared/issuable/sidebar', issuable: @merge_request)}"); -$('.issuable-sidebar').parent().effect('highlight') +$('aside.right-sidebar')[0].outerHTML= "#{escape_javascript(render 'shared/issuable/sidebar', issuable: @merge_request)}"; +$('aside.right-sidebar').effect('highlight') merge_request = new MergeRequest(); diff --git a/app/views/projects/show.atom.builder b/app/views/projects/show.atom.builder index 2468509242a..9b3d3f069d9 100644 --- a/app/views/projects/show.atom.builder +++ b/app/views/projects/show.atom.builder @@ -4,7 +4,7 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://sear xml.link href: namespace_project_url(@project.namespace, @project, format: :atom, private_token: current_user.try(:private_token)), rel: "self", type: "application/atom+xml" xml.link href: namespace_project_url(@project.namespace, @project), rel: "alternate", type: "text/html" xml.id namespace_project_url(@project.namespace, @project) - xml.updated @events[0].updated_at.xmlschema if @events[0? + xml.updated @events[0].updated_at.xmlschema if @events[0] @events.each do |event| event_to_atom(xml, event) diff --git a/app/views/shared/groups/_group.html.haml b/app/views/shared/groups/_group.html.haml index f7fe6b02641..289b0bfe1eb 100644 --- a/app/views/shared/groups/_group.html.haml +++ b/app/views/shared/groups/_group.html.haml @@ -21,7 +21,7 @@ = icon('users') = number_with_delimiter(group.users.count) - = image_tag group_icon(group), class: "avatar s46 hidden-xs" + = image_tag group_icon(group), class: "avatar s40 hidden-xs" = link_to group, class: 'group-name' do %span.item-title= group.name diff --git a/app/views/shared/issuable/_filter.html.haml b/app/views/shared/issuable/_filter.html.haml index 8d6f47b38ef..b7e350d27af 100644 --- a/app/views/shared/issuable/_filter.html.haml +++ b/app/views/shared/issuable/_filter.html.haml @@ -1,32 +1,5 @@ .issues-filters - .issues-state-filters - %ul.nav-links - - if defined?(type) && type == :merge_requests - - page_context_word = 'merge requests' - - else - - page_context_word = 'issues' - %li{class: ("active" if params[:state] == 'opened')} - = link_to page_filter_path(state: 'opened'), title: "Filter by #{page_context_word} that are currently opened." do - #{state_filters_text_for(:opened, @project)} - - - if defined?(type) && type == :merge_requests - %li{class: ("active" if params[:state] == 'merged')} - = link_to page_filter_path(state: 'merged'), title: 'Filter by merge requests that are currently merged.' do - #{state_filters_text_for(:merged, @project)} - - %li{class: ("active" if params[:state] == 'closed')} - = link_to page_filter_path(state: 'closed'), title: 'Filter by merge requests that are currently closed and unmerged.' do - #{state_filters_text_for(:closed, @project)} - - else - %li{class: ("active" if params[:state] == 'closed')} - = link_to page_filter_path(state: 'closed'), title: 'Filter by issues that are currently closed.' do - #{state_filters_text_for(:closed, @project)} - - %li{class: ("active" if params[:state] == 'all')} - = link_to page_filter_path(state: 'all'), title: "Show all #{page_context_word}." do - #{state_filters_text_for(:all, @project)} - - .issues-details-filters.gray-content-block + .issues-details-filters.gray-content-block.second-block = form_tag page_filter_path(without: [:assignee_id, :author_id, :milestone_title, :label_name]), method: :get, class: 'filter-form' do - if controller.controller_name == 'issues' && can?(current_user, :admin_issue, @project) .check-all-holder diff --git a/app/views/shared/issuable/_nav.html.haml b/app/views/shared/issuable/_nav.html.haml new file mode 100644 index 00000000000..a6970b7eebb --- /dev/null +++ b/app/views/shared/issuable/_nav.html.haml @@ -0,0 +1,25 @@ +%ul.nav-links.issues-state-filters + - if defined?(type) && type == :merge_requests + - page_context_word = 'merge requests' + - else + - page_context_word = 'issues' + %li{class: ("active" if params[:state] == 'opened')} + = link_to page_filter_path(state: 'opened'), title: "Filter by #{page_context_word} that are currently opened." do + #{state_filters_text_for(:opened, @project)} + + - if defined?(type) && type == :merge_requests + %li{class: ("active" if params[:state] == 'merged')} + = link_to page_filter_path(state: 'merged'), title: 'Filter by merge requests that are currently merged.' do + #{state_filters_text_for(:merged, @project)} + + %li{class: ("active" if params[:state] == 'closed')} + = link_to page_filter_path(state: 'closed'), title: 'Filter by merge requests that are currently closed and unmerged.' do + #{state_filters_text_for(:closed, @project)} + - else + %li{class: ("active" if params[:state] == 'closed')} + = link_to page_filter_path(state: 'closed'), title: 'Filter by issues that are currently closed.' do + #{state_filters_text_for(:closed, @project)} + + %li{class: ("active" if params[:state] == 'all')} + = link_to page_filter_path(state: 'all'), title: "Show all #{page_context_word}." do + #{state_filters_text_for(:all, @project)} diff --git a/app/views/shared/issuable/_participants.html.haml b/app/views/shared/issuable/_participants.html.haml index da6bacbb74a..ea61935487c 100644 --- a/app/views/shared/issuable/_participants.html.haml +++ b/app/views/shared/issuable/_participants.html.haml @@ -1,4 +1,8 @@ .block.participants + .sidebar-collapsed-icon + = icon('users') + %span + = participants.count .title = pluralize participants.count, "participant" - participants.each do |participant| diff --git a/app/views/shared/issuable/_search_form.html.haml b/app/views/shared/issuable/_search_form.html.haml index 6672ea79629..afad48499b7 100644 --- a/app/views/shared/issuable/_search_form.html.haml +++ b/app/views/shared/issuable/_search_form.html.haml @@ -1,9 +1,8 @@ -= form_tag(path, method: :get, id: "issue_search_form", class: 'pull-left issue-search-form') do - .append-right-10.hidden-xs.hidden-sm - = search_field_tag :issue_search, params[:issue_search], { placeholder: 'Filter by name ...', class: 'form-control issue_search search-text-input', spellcheck: false } - = hidden_field_tag :state, params['state'] - = hidden_field_tag :scope, params['scope'] - = hidden_field_tag :assignee_id, params['assignee_id'] - = hidden_field_tag :author_id, params['author_id'] - = hidden_field_tag :milestone_id, params['milestone_id'] - = hidden_field_tag :label_id, params['label_id'] += form_tag(path, method: :get, id: "issue_search_form", class: 'issue-search-form') do + = search_field_tag :issue_search, params[:issue_search], { placeholder: 'Filter by name ...', class: 'form-control issue_search search-text-input input-short', spellcheck: false } + = hidden_field_tag :state, params['state'] + = hidden_field_tag :scope, params['scope'] + = hidden_field_tag :assignee_id, params['assignee_id'] + = hidden_field_tag :author_id, params['author_id'] + = hidden_field_tag :milestone_id, params['milestone_id'] + = hidden_field_tag :label_id, params['label_id'] diff --git a/app/views/shared/issuable/_sidebar.html.haml b/app/views/shared/issuable/_sidebar.html.haml index 3092ff54242..75a7d9be2c1 100644 --- a/app/views/shared/issuable/_sidebar.html.haml +++ b/app/views/shared/issuable/_sidebar.html.haml @@ -1,88 +1,132 @@ -.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') +%aside.right-sidebar{ class: sidebar_gutter_collapsed_class } + .issuable-sidebar + .block + %span.issuable-count.pull-left + = issuable.iid + of + = issuable_count(:all, @project) + %span.pull-right + %a.gutter-toggle{href: '#'} + - if sidebar_gutter_collapsed? + = icon('angle-double-left') + - else + = icon('angle-double-right') + .issuable-nav.pull-right.btn-group{role: 'group', "aria-label" => '...'} + - if has_prev_issuable?(@project, issuable.id) + = link_to 'Prev', issuable_link_prev(@project, issuable), class: 'btn btn-default' - else - .light None + %a.btn.btn-default.disabled{href: '#'} + Prev + - if has_next_issuable?(@project, issuable.id) + = link_to 'Next', issuable_link_next(@project, issuable), class: 'btn btn-default' + - else + %a.btn.btn-default.disabled{href: '#'} + Next - .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) + = form_for [@project.namespace.becomes(Namespace), @project, issuable], remote: true, html: {class: 'issuable-context-form inline-update js-issuable-update'} do |f| + .block.assignee + .sidebar-collapsed-icon + - if issuable.assignee + = link_to_member_avatar(issuable.assignee, size: 24) + - else + = icon('user') + .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 + .sidebar-collapsed-icon + = icon('balance-scale') + %span + - if issuable.milestone + = issuable.milestone.title + - else + No .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.labels + .sidebar-collapsed-icon + = icon('tags') + %span + = issuable.labels.count + .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, type: issuable.to_ability_name) + - 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) + %hr + - if current_user + - subscribed = issuable.subscribed?(current_user) + .block.light + .sidebar-collapsed-icon + = icon('rss') + .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) + - project_ref = cross_project_reference(@project, issuable) + .block.project-reference + .sidebar-collapsed-icon + = icon('clipboard') + .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(); diff --git a/app/views/shared/projects/_list.html.haml b/app/views/shared/projects/_list.html.haml index b3f45373f6b..67edb264b7e 100644 --- a/app/views/shared/projects/_list.html.haml +++ b/app/views/shared/projects/_list.html.haml @@ -8,18 +8,22 @@ - show_last_commit_as_description = false unless local_assigns[:show_last_commit_as_description] == true %ul.projects-list - - projects.each_with_index do |project, i| - - css_class = (i >= projects_limit) ? 'hide' : nil - = render "shared/projects/project", project: project, skip_namespace: skip_namespace, - avatar: avatar, stars: stars, css_class: css_class, ci: ci, use_creator_avatar: use_creator_avatar, - forks: forks, show_last_commit_as_description: show_last_commit_as_description + - if projects.any? + - projects.each_with_index do |project, i| + - css_class = (i >= projects_limit) ? 'hide' : nil + = render "shared/projects/project", project: project, skip_namespace: skip_namespace, + avatar: avatar, stars: stars, css_class: css_class, ci: ci, use_creator_avatar: use_creator_avatar, + forks: forks, show_last_commit_as_description: show_last_commit_as_description - - if projects.size > projects_limit - %li.bottom.center - .light - #{projects_limit} of #{pluralize(projects.count, 'project')} displayed. - = link_to '#', class: 'js-expand' do - Show all + - if projects.size > projects_limit && projects.kind_of?(Array) + %li.bottom.center + .light + #{projects_limit} of #{pluralize(projects.count, 'project')} displayed. + = link_to '#', class: 'js-expand' do + Show all + = paginate projects, theme: "gitlab" if !projects.kind_of?(Array) + - else + %h3 No projects found :javascript new ProjectsList(); diff --git a/app/views/shared/projects/_project.html.haml b/app/views/shared/projects/_project.html.haml index e196fc51d2d..00bf9dcd2d5 100644 --- a/app/views/shared/projects/_project.html.haml +++ b/app/views/shared/projects/_project.html.haml @@ -16,9 +16,9 @@ - if avatar .dash-project-avatar - if use_creator_avatar - = image_tag avatar_icon(project.creator.email, 46), class: "avatar s46", alt:'' + = image_tag avatar_icon(project.creator.email, 40), class: "avatar s40", alt:'' - else - = project_icon(project, alt: '', class: 'avatar project-avatar s46') + = project_icon(project, alt: '', class: 'avatar project-avatar s40') %span.project-full-name %span.namespace-name - if project.namespace && !skip_namespace |