summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKamil Trzcinski <ayufan@ayufan.eu>2016-02-05 20:15:32 +0100
committerKamil Trzcinski <ayufan@ayufan.eu>2016-02-05 20:15:32 +0100
commit170ca8435a6b881231476b372122cf7e5b028736 (patch)
treeb3c762ef01268462b0b674b2d7f353e2a3a6cf48
parenta7c441aa17ba64eb702b583ac9198cdace599d2e (diff)
parent3a98279243e7a49a334c7eb6f806cd2b2072fbed (diff)
downloadgitlab-ce-170ca8435a6b881231476b372122cf7e5b028736.tar.gz
Merge branch 'master' into ci-permissions
# Conflicts: # db/schema.rb
-rw-r--r--CHANGELOG4
-rw-r--r--app/assets/javascripts/application.js.coffee89
-rw-r--r--app/assets/javascripts/dashboard.js.coffee33
-rw-r--r--app/assets/javascripts/dispatcher.js.coffee2
-rw-r--r--app/assets/javascripts/issuable_context.js.coffee14
-rw-r--r--app/assets/javascripts/projects_list.js.coffee2
-rw-r--r--app/assets/stylesheets/framework/avatar.scss4
-rw-r--r--app/assets/stylesheets/framework/buttons.scss2
-rw-r--r--app/assets/stylesheets/framework/issue_box.scss2
-rw-r--r--app/assets/stylesheets/framework/lists.scss1
-rw-r--r--app/assets/stylesheets/framework/mobile.scss2
-rw-r--r--app/assets/stylesheets/framework/nav.scss4
-rw-r--r--app/assets/stylesheets/framework/sidebar.scss31
-rw-r--r--app/assets/stylesheets/framework/variables.scss21
-rw-r--r--app/assets/stylesheets/pages/dashboard.scss4
-rw-r--r--app/assets/stylesheets/pages/events.scss9
-rw-r--r--app/assets/stylesheets/pages/issuable.scss134
-rw-r--r--app/assets/stylesheets/pages/issues.scss6
-rw-r--r--app/assets/stylesheets/pages/projects.scss5
-rw-r--r--app/controllers/admin/broadcast_messages_controller.rb2
-rw-r--r--app/controllers/application_controller.rb3
-rw-r--r--app/controllers/dashboard/projects_controller.rb26
-rw-r--r--app/controllers/explore/projects_controller.rb12
-rw-r--r--app/controllers/groups_controller.rb1
-rw-r--r--app/controllers/omniauth_callbacks_controller.rb9
-rw-r--r--app/controllers/users_controller.rb3
-rw-r--r--app/helpers/application_helper.rb82
-rw-r--r--app/helpers/labels_helper.rb13
-rw-r--r--app/helpers/nav_helper.rb23
-rw-r--r--app/helpers/projects_helper.rb6
-rw-r--r--app/models/event.rb2
-rw-r--r--app/views/admin/broadcast_messages/index.html.haml2
-rw-r--r--app/views/admin/builds/index.html.haml13
-rw-r--r--app/views/admin/dashboard/index.html.haml5
-rw-r--r--app/views/dashboard/_projects_head.html.haml3
-rw-r--r--app/views/dashboard/issues.html.haml16
-rw-r--r--app/views/dashboard/merge_requests.html.haml7
-rw-r--r--app/views/dashboard/projects/_projects.html.haml3
-rw-r--r--app/views/events/_event.html.haml4
-rw-r--r--app/views/explore/projects/index.html.haml1
-rw-r--r--app/views/explore/projects/starred.html.haml3
-rw-r--r--app/views/explore/projects/trending.html.haml2
-rw-r--r--app/views/groups/issues.html.haml16
-rw-r--r--app/views/groups/merge_requests.html.haml7
-rw-r--r--app/views/help/_shortcuts.html.haml8
-rw-r--r--app/views/layouts/_page.html.haml2
-rw-r--r--app/views/layouts/_search.html.haml2
-rw-r--r--app/views/profiles/accounts/show.html.haml51
-rw-r--r--app/views/projects/issues/index.html.haml21
-rw-r--r--app/views/projects/issues/show.html.haml16
-rw-r--r--app/views/projects/issues/update.js.haml6
-rw-r--r--app/views/projects/merge_requests/_merge_request.html.haml2
-rw-r--r--app/views/projects/merge_requests/_show.html.haml7
-rw-r--r--app/views/projects/merge_requests/index.html.haml17
-rw-r--r--app/views/projects/merge_requests/show/_mr_box.html.haml5
-rw-r--r--app/views/projects/merge_requests/show/_mr_title.html.haml5
-rw-r--r--app/views/projects/merge_requests/update.js.haml4
-rw-r--r--app/views/projects/show.atom.builder2
-rw-r--r--app/views/shared/groups/_group.html.haml2
-rw-r--r--app/views/shared/issuable/_filter.html.haml29
-rw-r--r--app/views/shared/issuable/_nav.html.haml25
-rw-r--r--app/views/shared/issuable/_participants.html.haml4
-rw-r--r--app/views/shared/issuable/_search_form.html.haml17
-rw-r--r--app/views/shared/issuable/_sidebar.html.haml190
-rw-r--r--app/views/shared/projects/_list.html.haml26
-rw-r--r--app/views/shared/projects/_project.html.haml4
-rw-r--r--db/migrate/20160129135155_remove_dot_atom_path_ending_of_projects.rb80
-rw-r--r--doc/api/deploy_key_multiple_projects.md18
-rw-r--r--doc/api/session.md42
-rw-r--r--doc/customization/issue_closing.md2
-rw-r--r--doc/development/doc_styleguide.md11
-rw-r--r--doc/install/installation.md5
-rw-r--r--lib/gitlab/backend/shell.rb2
-rw-r--r--lib/gitlab/database.rb38
-rw-r--r--lib/gitlab/regex.rb4
-rw-r--r--spec/controllers/projects_controller_spec.rb8
-rw-r--r--spec/features/admin/admin_builds_spec.rb12
-rw-r--r--spec/helpers/labels_helper_spec.rb33
-rw-r--r--spec/helpers/search_helper_spec.rb4
-rw-r--r--spec/lib/gitlab/database_spec.rb20
80 files changed, 958 insertions, 399 deletions
diff --git a/CHANGELOG b/CHANGELOG
index f434e361281..d43b8f69063 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -13,9 +13,12 @@ v 8.5.0 (unreleased)
set it up
- Fix diff comments loaded by AJAX to load comment with diff in discussion tab
- Whitelist raw "abbr" elements when parsing Markdown (Benedict Etzel)
+ - Fix label links for a merge request pointing to issues list
- Don't vendor minified JS
- Display 404 error on group not found
- Track project import failure
+ - Support Two-factor Authentication for LDAP users
+ - Display database type and version in Administration dashboard
- Fix visibility level text in admin area (Zeger-Jan van de Weg)
- Warn admin during OAuth of granting admin rights (Zeger-Jan van de Weg)
- Update the ExternalIssue regex pattern (Blake Hitchcock)
@@ -24,6 +27,7 @@ v 8.5.0 (unreleased)
- Fix API to keep request parameters in Link header (Michael Potthoff)
- Deprecate API "merge_request/:merge_request_id/comments". Use "merge_requests/:merge_request_id/notes" instead
- Deprecate API "merge_request/:merge_request_id/...". Use "merge_requests/:merge_request_id/..." instead
+ - Prevent parse error when name of project ends with .atom and prevent path issues
- Mark inline difference between old and new paths when a file is renamed
- Support Akismet spam checking for creation of issues via API (Stan Hu)
- Improve UI consistency between projects and groups lists
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)}
&middot;
= time_ago_with_tooltip(@issue.created_at, placement: 'bottom', html_class: 'issue_created_ago')
- - if @issue.updated_at != @issue.created_at
- %span
- &middot;
- = 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?
&nbsp;
- 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?
&nbsp;
%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)}
&middot;
= time_ago_with_tooltip(@merge_request.created_at)
- - if @merge_request.updated_at != @merge_request.created_at
- %span
- &middot;
- = 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
diff --git a/db/migrate/20160129135155_remove_dot_atom_path_ending_of_projects.rb b/db/migrate/20160129135155_remove_dot_atom_path_ending_of_projects.rb
new file mode 100644
index 00000000000..091de54978b
--- /dev/null
+++ b/db/migrate/20160129135155_remove_dot_atom_path_ending_of_projects.rb
@@ -0,0 +1,80 @@
+class RemoveDotAtomPathEndingOfProjects < ActiveRecord::Migration
+ include Gitlab::ShellAdapter
+
+ class ProjectPath
+ attr_reader :old_path, :id, :namespace_path
+
+ def initialize(old_path, id, namespace_path, namespace_id)
+ @old_path = old_path
+ @id = id
+ @namespace_path = namespace_path
+ @namespace_id = namespace_id
+ end
+
+ def clean_path
+ @_clean_path ||= PathCleaner.clean(@old_path, @namespace_id)
+ end
+ end
+
+ class PathCleaner
+ def initialize(path, namespace_id)
+ @namespace_id = namespace_id
+ @path = path
+ end
+
+ def self.clean(*args)
+ new(*args).clean
+ end
+
+ def clean
+ path = cleaned_path
+ count = 0
+ while path_exists?(path)
+ path = "#{cleaned_path}#{count}"
+ count += 1
+ end
+ path
+ end
+
+ private
+
+ def cleaned_path
+ @_cleaned_path ||= @path.gsub(/\.atom\z/, '-atom')
+ end
+
+ def path_exists?(path)
+ Project.find_by_path_and_namespace_id(path, @namespace_id)
+ end
+ end
+
+ def projects_with_dot_atom
+ select_all("SELECT p.id, p.path, n.path as namespace_path, n.id as namespace_id FROM projects p inner join namespaces n on n.id = p.namespace_id WHERE lower(p.path) LIKE '%.atom'")
+ end
+
+ def up
+ projects_with_dot_atom.each do |project|
+ project_path = ProjectPath.new(project['path'], project['id'], project['namespace_path'], project['namespace_id'])
+ clean_path(project_path) if rename_project_repo(project_path)
+ end
+ end
+
+ private
+
+ def clean_path(project_path)
+ execute "UPDATE projects SET path = #{sanitize(project_path.clean_path)} WHERE id = #{project_path.id}"
+ end
+
+ def rename_project_repo(project_path)
+ old_path_with_namespace = File.join(project_path.namespace_path, project_path.old_path)
+ new_path_with_namespace = File.join(project_path.namespace_path, project_path.clean_path)
+
+ gitlab_shell.mv_repository("#{old_path_with_namespace}.wiki", "#{new_path_with_namespace}.wiki")
+ gitlab_shell.mv_repository(old_path_with_namespace, new_path_with_namespace)
+ rescue
+ false
+ end
+
+ def sanitize(value)
+ ActiveRecord::Base.connection.quote(value)
+ end
+end
diff --git a/doc/api/deploy_key_multiple_projects.md b/doc/api/deploy_key_multiple_projects.md
index 1a5a458905e..3ad836f51b5 100644
--- a/doc/api/deploy_key_multiple_projects.md
+++ b/doc/api/deploy_key_multiple_projects.md
@@ -1,25 +1,29 @@
# Adding deploy keys to multiple projects
-If you want to easily add the same deploy key to multiple projects in the same group, this can be achieved quite easily with the API.
+If you want to easily add the same deploy key to multiple projects in the same
+group, this can be achieved quite easily with the API.
-First, find the ID of the projects you're interested in, by either listing all projects:
+First, find the ID of the projects you're interested in, by either listing all
+projects:
```
-curl --header 'PRIVATE-TOKEN: abcdef' https://gitlab.com/api/v3/projects
+curl -H 'PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK' https://gitlab.example.com/api/v3/projects
```
-Or finding the id of a group and then listing all projects in that group:
+Or finding the ID of a group and then listing all projects in that group:
```
-curl --header 'PRIVATE-TOKEN: abcdef' https://gitlab.com/api/v3/groups
+curl -H 'PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK' https://gitlab.example.com/api/v3/groups
# For group 1234:
-curl --header 'PRIVATE-TOKEN: abcdef' https://gitlab.com/api/v3/groups/1234
+curl -H 'PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK' https://gitlab.example.com/api/v3/groups/1234
```
With those IDs, add the same deploy key to all:
+
```
for project_id in 321 456 987; do
- curl -X POST --data '{"title": "my key", "key": "ssh-rsa AAAA..."}' --header 'PRIVATE-TOKEN: abcdef' https://gitlab.com/api/v3/projects/${project_id}/keys
+ curl -X POST -H "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" -H "Content-Type: application/json" \
+ --data '{"title": "my key", "key": "ssh-rsa AAAA..."}' https://gitlab.example.com/api/v3/projects/${project_id}/keys
done
```
diff --git a/doc/api/session.md b/doc/api/session.md
index 47c1c8a7a49..71e93d0bb0a 100644
--- a/doc/api/session.md
+++ b/doc/api/session.md
@@ -1,39 +1,47 @@
# Session
-Login to get private token
+You can login with both GitLab and LDAP credentials in order to obtain the
+private token.
```
POST /session
```
-Parameters:
+| Attribute | Type | Required | Description |
+| ---------- | ------- | -------- | -------- |
+| `login` | string | yes | The username of the user|
+| `email` | string | yes if login is not provided | The email of the user |
+| `password` | string | yes | The password of the user |
-- `login` (required) - The login of user
-- `email` (required if login missing) - The email of user
-- `password` (required) - Valid password
-
-**You can login with both GitLab and LDAP credentials now**
+```bash
+curl -X POST "https://gitlab.example.com/api/v3/session?login=john_smith&password=strongpassw0rd"
+```
+Example response:
```json
{
- "id": 1,
- "username": "john_smith",
- "email": "john@example.com",
"name": "John Smith",
- "private_token": "dd34asd13as",
- "blocked": false,
- "created_at": "2012-05-23T08:00:58Z",
+ "username": "john_smith",
+ "id": 32,
+ "state": "active",
+ "avatar_url": null,
+ "created_at": "2015-01-29T21:07:19.440Z",
+ "is_admin": true,
"bio": null,
"skype": "",
"linkedin": "",
"twitter": "",
"website_url": "",
- "dark_scheme": false,
+ "email": "john@example.com",
"theme_id": 1,
- "is_admin": false,
+ "color_scheme_id": 1,
+ "projects_limit": 10,
+ "current_sign_in_at": "2015-07-07T07:10:58.392Z",
+ "identities": [],
"can_create_group": true,
- "can_create_team": true,
- "can_create_project": true
+ "can_create_project": true,
+ "two_factor_enabled": false,
+ "private_token": "9koXpg98eAheJpvBs5tK"
}
```
diff --git a/doc/customization/issue_closing.md b/doc/customization/issue_closing.md
index 00edfc97ed9..194b8e00299 100644
--- a/doc/customization/issue_closing.md
+++ b/doc/customization/issue_closing.md
@@ -16,7 +16,7 @@ Here, `%{issue_ref}` is a complex regular expression defined inside GitLab, that
For example:
```
-git commit -m "Awesome commit message (Fix #20, Fixes #21 and Closes group/otherproject#2). This commit is also related to #17 and fixes #18, #19 and https://gitlab.example.com/group/otherproject/issues/23."
+git commit -m "Awesome commit message (Fix #20, Fixes #21 and Closes group/otherproject#22). This commit is also related to #17 and fixes #18, #19 and https://gitlab.example.com/group/otherproject/issues/23."
```
will close `#18`, `#19`, `#20`, and `#21` in the project this commit is pushed to, as well as `#22` and `#23` in group/otherproject. `#17` won't be closed as it does not match the pattern. It also works with multiline commit messages.
diff --git a/doc/development/doc_styleguide.md b/doc/development/doc_styleguide.md
index caaa4032db2..96d1dffbc52 100644
--- a/doc/development/doc_styleguide.md
+++ b/doc/development/doc_styleguide.md
@@ -120,6 +120,17 @@ Inside the document:
`http://doc.gitlab.com/ce/administration/restart_gitlab.html`.
Replace `reconfigure` with `restart` where appropriate.
+## Installation guide
+
+- **Ruby:**
+ In [step 2 of the installation guide](../install/installation.md#2-ruby),
+ we install Ruby from source. Whenever there is a new version that needs to
+ be updated, remember to change it throughout the codeblock and also replace
+ the sha256sum (it can be found in the [downloads page][ruby-dl] of the Ruby
+ website).
+
+[ruby-dl]: https://www.ruby-lang.org/en/downloads/ "Ruby download website"
+
## API
Here is a list of must-have items. Use them in the exact order that appears
diff --git a/doc/install/installation.md b/doc/install/installation.md
index a2c23bd52e5..3eb9b1767c5 100644
--- a/doc/install/installation.md
+++ b/doc/install/installation.md
@@ -124,7 +124,7 @@ Download Ruby and compile it:
mkdir /tmp/ruby && cd /tmp/ruby
curl -O --progress https://cache.ruby-lang.org/pub/ruby/2.2/ruby-2.2.4.tar.gz
- echo 'e2e195a4a58133e3ad33b955c829bb536fa3c075 ruby-2.2.4.tar.gz' | shasum -c - && tar xzf ruby-2.2.4.tar.gz
+ echo 'b6eff568b48e0fda76e5a36333175df049b204e91217aa32a65153cc0cdcb761 ruby-2.2.4.tar.gz' | sha256sum -c - && tar xzf ruby-2.2.4.tar.gz
cd ruby-2.2.4
./configure --disable-install-rdoc
make
@@ -267,6 +267,9 @@ sudo usermod -aG redis git
sudo chmod -R u+rwX tmp/pids/
sudo chmod -R u+rwX tmp/sockets/
+ # Create the public/uploads/ directory
+ sudo -u git -H mkdir public/uploads/
+
# Make sure GitLab can write to the public/uploads/ directory
sudo chmod -R u+rwX public/uploads
diff --git a/lib/gitlab/backend/shell.rb b/lib/gitlab/backend/shell.rb
index 4c15d58d680..f751458ac66 100644
--- a/lib/gitlab/backend/shell.rb
+++ b/lib/gitlab/backend/shell.rb
@@ -47,7 +47,7 @@ module Gitlab
# new_path - new project path with namespace
#
# Ex.
- # mv_repository("gitlab/gitlab-ci", "randx/gitlab-ci-new.git")
+ # mv_repository("gitlab/gitlab-ci", "randx/gitlab-ci-new")
#
def mv_repository(path, new_path)
Gitlab::Utils.system_silent([gitlab_shell_projects_path, 'mv-project',
diff --git a/lib/gitlab/database.rb b/lib/gitlab/database.rb
index de77a6fbff1..6ebb8027553 100644
--- a/lib/gitlab/database.rb
+++ b/lib/gitlab/database.rb
@@ -1,16 +1,23 @@
module Gitlab
module Database
+ def self.adapter_name
+ connection.adapter_name
+ end
+
def self.mysql?
- ActiveRecord::Base.connection.adapter_name.downcase == 'mysql2'
+ adapter_name.downcase == 'mysql2'
end
def self.postgresql?
- ActiveRecord::Base.connection.adapter_name.downcase == 'postgresql'
+ adapter_name.downcase == 'postgresql'
+ end
+
+ def self.version
+ database_version.match(/\A(?:PostgreSQL |)([^\s]+).*\z/)[1]
end
def true_value
- case ActiveRecord::Base.connection.adapter_name.downcase
- when 'postgresql'
+ if self.class.postgresql?
"'t'"
else
1
@@ -18,12 +25,31 @@ module Gitlab
end
def false_value
- case ActiveRecord::Base.connection.adapter_name.downcase
- when 'postgresql'
+ if self.class.postgresql?
"'f'"
else
0
end
end
+
+ private
+
+ def self.connection
+ ActiveRecord::Base.connection
+ end
+
+ def self.database_version
+ row = connection.execute("SELECT VERSION()").first
+
+ if postgresql?
+ row['version']
+ else
+ row.first
+ end
+ end
+
+ def connection
+ self.class.connection
+ end
end
end
diff --git a/lib/gitlab/regex.rb b/lib/gitlab/regex.rb
index 5c35c5b1450..ace906a6f59 100644
--- a/lib/gitlab/regex.rb
+++ b/lib/gitlab/regex.rb
@@ -34,12 +34,12 @@ module Gitlab
def project_path_regex
- @project_path_regex ||= /\A[a-zA-Z0-9_.][a-zA-Z0-9_\-\.]*(?<!\.git)\z/.freeze
+ @project_path_regex ||= /\A[a-zA-Z0-9_.][a-zA-Z0-9_\-\.]*(?<!\.git|\.atom)\z/.freeze
end
def project_path_regex_message
"can contain only letters, digits, '_', '-' and '.'. " \
- "Cannot start with '-' or end in '.git'" \
+ "Cannot start with '-', end in '.git' or end in '.atom'" \
end
diff --git a/spec/controllers/projects_controller_spec.rb b/spec/controllers/projects_controller_spec.rb
index 665526fde93..6eee4dfe229 100644
--- a/spec/controllers/projects_controller_spec.rb
+++ b/spec/controllers/projects_controller_spec.rb
@@ -86,6 +86,14 @@ describe ProjectsController do
end
end
end
+
+ context "when the url contains .atom" do
+ let(:public_project_with_dot_atom) { build(:project, :public, name: 'my.atom', path: 'my.atom') }
+
+ it 'expect an error creating the project' do
+ expect(public_project_with_dot_atom).not_to be_valid
+ end
+ end
end
describe "#destroy" do
diff --git a/spec/features/admin/admin_builds_spec.rb b/spec/features/admin/admin_builds_spec.rb
index b955d0b0c46..2e9851fb442 100644
--- a/spec/features/admin/admin_builds_spec.rb
+++ b/spec/features/admin/admin_builds_spec.rb
@@ -18,7 +18,7 @@ describe 'Admin Builds' do
visit admin_builds_path
- expect(page).to have_selector('.project-issuable-filter li.active', text: 'All')
+ expect(page).to have_selector('.nav-links li.active', text: 'All')
expect(page.all('.build-link').size).to eq(4)
expect(page).to have_link 'Cancel all'
end
@@ -28,7 +28,7 @@ describe 'Admin Builds' do
it 'shows a message' do
visit admin_builds_path
- expect(page).to have_selector('.project-issuable-filter li.active', text: 'All')
+ expect(page).to have_selector('.nav-links li.active', text: 'All')
expect(page).to have_content 'No builds to show'
expect(page).not_to have_link 'Cancel all'
end
@@ -44,7 +44,7 @@ describe 'Admin Builds' do
visit admin_builds_path(scope: :running)
- expect(page).to have_selector('.project-issuable-filter li.active', text: 'Running')
+ expect(page).to have_selector('.nav-links li.active', text: 'Running')
expect(page.find('.build-link')).to have_content(build1.id)
expect(page.find('.build-link')).not_to have_content(build2.id)
expect(page.find('.build-link')).not_to have_content(build3.id)
@@ -58,7 +58,7 @@ describe 'Admin Builds' do
visit admin_builds_path(scope: :running)
- expect(page).to have_selector('.project-issuable-filter li.active', text: 'Running')
+ expect(page).to have_selector('.nav-links li.active', text: 'Running')
expect(page).to have_content 'No builds to show'
expect(page).not_to have_link 'Cancel all'
end
@@ -74,7 +74,7 @@ describe 'Admin Builds' do
visit admin_builds_path(scope: :finished)
- expect(page).to have_selector('.project-issuable-filter li.active', text: 'Finished')
+ expect(page).to have_selector('.nav-links li.active', text: 'Finished')
expect(page.find('.build-link')).not_to have_content(build1.id)
expect(page.find('.build-link')).not_to have_content(build2.id)
expect(page.find('.build-link')).to have_content(build3.id)
@@ -88,7 +88,7 @@ describe 'Admin Builds' do
visit admin_builds_path(scope: :finished)
- expect(page).to have_selector('.project-issuable-filter li.active', text: 'Finished')
+ expect(page).to have_selector('.nav-links li.active', text: 'Finished')
expect(page).to have_content 'No builds to show'
expect(page).to have_link 'Cancel all'
end
diff --git a/spec/helpers/labels_helper_spec.rb b/spec/helpers/labels_helper_spec.rb
index 0b9176357bc..4f129eca183 100644
--- a/spec/helpers/labels_helper_spec.rb
+++ b/spec/helpers/labels_helper_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe LabelsHelper do
describe 'link_to_label' do
let(:project) { create(:empty_project) }
- let(:label) { create(:label, project: project) }
+ let(:label) { create(:label, project: project) }
context 'with @project set' do
before do
@@ -11,34 +11,31 @@ describe LabelsHelper do
end
it 'uses the instance variable' do
- expect(label).not_to receive(:project)
- link_to_label(label)
+ expect(link_to_label(label)).to match %r{<a href="/#{@project.to_reference}/issues\?label_name=#{label.name}">.*</a>}
end
end
context 'without @project set' do
it "uses the label's project" do
- expect(label).to receive(:project).and_return(project)
- link_to_label(label)
+ expect(link_to_label(label)).to match %r{<a href="/#{label.project.to_reference}/issues\?label_name=#{label.name}">.*</a>}
end
end
- context 'with a named project argument' do
- it 'uses the provided project' do
- arg = double('project')
- expect(arg).to receive(:namespace).and_return('foo')
- expect(arg).to receive(:to_param).and_return('foo')
+ context 'with a project argument' do
+ let(:another_project) { double('project', namespace: 'foo3', to_param: 'bar3') }
- link_to_label(label, project: arg)
+ it 'links to merge requests page' do
+ expect(link_to_label(label, project: another_project)).to match %r{<a href="/foo3/bar3/issues\?label_name=#{label.name}">.*</a>}
end
+ end
- it 'takes precedence over other types' do
- @project = project
- expect(@project).not_to receive(:namespace)
- expect(label).not_to receive(:project)
-
- arg = double('project', namespace: 'foo', to_param: 'foo')
- link_to_label(label, project: arg)
+ context 'with a type argument' do
+ ['issue', :issue, 'merge_request', :merge_request].each do |type|
+ context "set to #{type}" do
+ it 'links to correct page' do
+ expect(link_to_label(label, type: type)).to match %r{<a href="/#{label.project.to_reference}/#{type.to_s.pluralize}\?label_name=#{label.name}">.*</a>}
+ end
+ end
end
end
diff --git a/spec/helpers/search_helper_spec.rb b/spec/helpers/search_helper_spec.rb
index f0d553f5f1d..601b6915e27 100644
--- a/spec/helpers/search_helper_spec.rb
+++ b/spec/helpers/search_helper_spec.rb
@@ -42,9 +42,9 @@ describe SearchHelper do
expect(search_autocomplete_opts(project.name).size).to eq(1)
end
- it "includes the public group" do
+ it "should not include the public group" do
group = create(:group)
- expect(search_autocomplete_opts(group.name).size).to eq(1)
+ expect(search_autocomplete_opts(group.name).size).to eq(0)
end
context "with a current project" do
diff --git a/spec/lib/gitlab/database_spec.rb b/spec/lib/gitlab/database_spec.rb
index 8461e8ce50d..bd8688fefa1 100644
--- a/spec/lib/gitlab/database_spec.rb
+++ b/spec/lib/gitlab/database_spec.rb
@@ -14,4 +14,24 @@ describe Gitlab::Database, lib: true do
it { is_expected.to satisfy { |val| val == true || val == false } }
end
+
+ describe '.version' do
+ context "on mysql" do
+ it "extracts the version number" do
+ allow(described_class).to receive(:database_version).
+ and_return("5.7.12-standard")
+
+ expect(described_class.version).to eq '5.7.12-standard'
+ end
+ end
+
+ context "on postgresql" do
+ it "extracts the version number" do
+ allow(described_class).to receive(:database_version).
+ and_return("PostgreSQL 9.4.4 on x86_64-apple-darwin14.3.0")
+
+ expect(described_class.version).to eq '9.4.4'
+ end
+ end
+ end
end