summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/awards_handler.coffee15
-rw-r--r--app/assets/javascripts/compare.js.coffee67
-rw-r--r--app/assets/javascripts/gl_dropdown.js.coffee41
-rw-r--r--app/assets/javascripts/merge_request_tabs.js.coffee3
-rw-r--r--app/assets/javascripts/merge_request_widget.js.coffee8
-rw-r--r--app/assets/javascripts/milestone_select.js.coffee8
-rw-r--r--app/assets/javascripts/sidebar.js.coffee1
-rw-r--r--app/assets/javascripts/subscription.js.coffee4
-rw-r--r--app/assets/javascripts/todos.js.coffee9
-rw-r--r--app/assets/stylesheets/framework/buttons.scss29
-rw-r--r--app/assets/stylesheets/framework/dropdowns.scss4
-rw-r--r--app/assets/stylesheets/framework/files.scss6
-rw-r--r--app/assets/stylesheets/framework/gitlab-theme.scss6
-rw-r--r--app/assets/stylesheets/framework/header.scss4
-rw-r--r--app/assets/stylesheets/framework/markdown_area.scss1
-rw-r--r--app/assets/stylesheets/framework/sidebar.scss123
-rw-r--r--app/assets/stylesheets/framework/timeline.scss4
-rw-r--r--app/assets/stylesheets/framework/variables.scss28
-rw-r--r--app/assets/stylesheets/highlight/solarized_light.scss4
-rw-r--r--app/assets/stylesheets/highlight/white.scss24
-rw-r--r--app/assets/stylesheets/pages/commit.scss2
-rw-r--r--app/assets/stylesheets/pages/commits.scss5
-rw-r--r--app/assets/stylesheets/pages/detail_page.scss8
-rw-r--r--app/assets/stylesheets/pages/diff.scss22
-rw-r--r--app/assets/stylesheets/pages/help.scss3
-rw-r--r--app/assets/stylesheets/pages/labels.scss58
-rw-r--r--app/assets/stylesheets/pages/merge_requests.scss79
-rw-r--r--app/assets/stylesheets/pages/note_form.scss11
-rw-r--r--app/assets/stylesheets/pages/notes.scss31
-rw-r--r--app/controllers/admin/projects_controller.rb2
-rw-r--r--app/controllers/application_controller.rb10
-rw-r--r--app/controllers/groups/milestones_controller.rb31
-rw-r--r--app/controllers/omniauth_callbacks_controller.rb2
-rw-r--r--app/controllers/projects/application_controller.rb4
-rw-r--r--app/controllers/projects/badges_controller.rb9
-rw-r--r--app/controllers/projects/branches_controller.rb2
-rw-r--r--app/controllers/projects/merge_requests_controller.rb6
-rw-r--r--app/controllers/projects/refs_controller.rb2
-rw-r--r--app/controllers/projects/wikis_controller.rb14
-rw-r--r--app/controllers/sessions_controller.rb15
-rw-r--r--app/helpers/blob_helper.rb6
-rw-r--r--app/helpers/commits_helper.rb6
-rw-r--r--app/helpers/form_helper.rb18
-rw-r--r--app/helpers/gitlab_markdown_helper.rb23
-rw-r--r--app/helpers/issues_helper.rb33
-rw-r--r--app/helpers/notes_helper.rb7
-rw-r--r--app/models/repository.rb2
-rw-r--r--app/services/git_push_service.rb10
-rw-r--r--app/services/milestones/create_service.rb2
-rw-r--r--app/views/abuse_reports/new.html.haml6
-rw-r--r--app/views/admin/appearances/_form.html.haml5
-rw-r--r--app/views/admin/application_settings/_form.html.haml6
-rw-r--r--app/views/admin/applications/_form.html.haml7
-rw-r--r--app/views/admin/broadcast_messages/_form.html.haml6
-rw-r--r--app/views/admin/deploy_keys/new.html.haml6
-rw-r--r--app/views/admin/groups/_form.html.haml5
-rw-r--r--app/views/admin/hooks/index.html.haml6
-rw-r--r--app/views/admin/identities/_form.html.haml6
-rw-r--r--app/views/admin/labels/_form.html.haml8
-rw-r--r--app/views/admin/users/_form.html.haml6
-rw-r--r--app/views/doorkeeper/applications/_form.html.haml6
-rw-r--r--app/views/groups/edit.html.haml4
-rw-r--r--app/views/groups/milestones/new.html.haml8
-rw-r--r--app/views/groups/new.html.haml5
-rw-r--r--app/views/layouts/_collapse_button.html.haml4
-rw-r--r--app/views/layouts/_page.html.haml18
-rw-r--r--app/views/layouts/_search.html.haml4
-rw-r--r--app/views/layouts/nav/_admin.html.haml2
-rw-r--r--app/views/layouts/nav/_dashboard.html.haml7
-rw-r--r--app/views/layouts/nav/_group.html.haml10
-rw-r--r--app/views/layouts/nav/_profile.html.haml8
-rw-r--r--app/views/layouts/nav/_project.html.haml17
-rw-r--r--app/views/layouts/nav/_project_settings.html.haml7
-rw-r--r--app/views/layouts/project.html.haml6
-rw-r--r--app/views/profiles/keys/_form.html.haml6
-rw-r--r--app/views/profiles/notifications/show.html.haml6
-rw-r--r--app/views/profiles/passwords/edit.html.haml7
-rw-r--r--app/views/profiles/passwords/new.html.haml7
-rw-r--r--app/views/profiles/show.html.haml7
-rw-r--r--app/views/projects/_errors.html.haml5
-rw-r--r--app/views/projects/_md_preview.html.haml6
-rw-r--r--app/views/projects/badges/index.html.haml24
-rw-r--r--app/views/projects/commits/_commit.html.haml9
-rw-r--r--app/views/projects/deploy_keys/_form.html.haml6
-rw-r--r--app/views/projects/diffs/_diffs.html.haml2
-rw-r--r--app/views/projects/diffs/_file.html.haml12
-rw-r--r--app/views/projects/hooks/index.html.haml6
-rw-r--r--app/views/projects/labels/_form.html.haml8
-rw-r--r--app/views/projects/labels/_label.html.haml17
-rw-r--r--app/views/projects/merge_requests/_new_compare.html.haml116
-rw-r--r--app/views/projects/merge_requests/branch_from.html.haml1
-rw-r--r--app/views/projects/merge_requests/branch_from.js.haml3
-rw-r--r--app/views/projects/merge_requests/branch_to.html.haml1
-rw-r--r--app/views/projects/merge_requests/branch_to.js.haml3
-rw-r--r--app/views/projects/merge_requests/update_branches.html.haml5
-rw-r--r--app/views/projects/merge_requests/update_branches.js.haml9
-rw-r--r--app/views/projects/merge_requests/widget/_show.html.haml2
-rw-r--r--app/views/projects/milestones/_form.html.haml7
-rw-r--r--app/views/projects/notes/_diff_notes_with_reply.html.haml3
-rw-r--r--app/views/projects/notes/_diff_notes_with_reply_parallel.html.haml6
-rw-r--r--app/views/projects/notes/_note.html.haml4
-rw-r--r--app/views/projects/protected_branches/index.html.haml6
-rw-r--r--app/views/projects/variables/show.html.haml8
-rw-r--r--app/views/projects/wikis/_form.html.haml6
-rw-r--r--app/views/shared/_label_row.html.haml3
-rw-r--r--app/views/shared/_service_settings.html.haml7
-rw-r--r--app/views/shared/issuable/_form.html.haml23
-rw-r--r--app/views/shared/issuable/_sidebar.html.haml14
-rw-r--r--app/views/shared/snippets/_form.html.haml6
-rw-r--r--app/views/users/calendar.html.haml2
-rw-r--r--app/views/votes/_votes_block.html.haml4
111 files changed, 841 insertions, 511 deletions
diff --git a/app/assets/javascripts/awards_handler.coffee b/app/assets/javascripts/awards_handler.coffee
index 6a670d5e887..af4462ece38 100644
--- a/app/assets/javascripts/awards_handler.coffee
+++ b/app/assets/javascripts/awards_handler.coffee
@@ -22,8 +22,19 @@ class @AwardsHandler
emoji = $(this)
.find(".icon")
.data "emoji"
+
+ if emoji is "thumbsup" and awards_handler.didUserClickEmoji $(this), "thumbsdown"
+ awards_handler.addAward "thumbsdown"
+
+ else if emoji is "thumbsdown" and awards_handler.didUserClickEmoji $(this), "thumbsup"
+ awards_handler.addAward "thumbsup"
+
awards_handler.addAward emoji
+ didUserClickEmoji: (that, emoji) ->
+ if $(that).siblings("button:has([data-emoji=#{emoji}])").attr("data-original-title")
+ $(that).siblings("button:has([data-emoji=#{emoji}])").attr("data-original-title").indexOf('me') > -1
+
showEmojiMenu: ->
if $(".emoji-menu").length
if $(".emoji-menu").is ".is-visible"
@@ -105,7 +116,7 @@ class @AwardsHandler
if origTitle
authors = origTitle.split(', ')
authors.push("me")
- award_block.attr("title", authors.join(", "))
+ award_block.attr("data-original-title", authors.join(", "))
@resetTooltip(award_block)
resetTooltip: (award) ->
@@ -122,7 +133,7 @@ class @AwardsHandler
nodes = []
nodes.push(
- "<button class='btn award-control js-emoji-btn has-tooltip active' title='me'>",
+ "<button class='btn award-control js-emoji-btn has-tooltip active' data-original-title='me'>",
"<div class='icon emoji-icon #{emojiCssClass}' data-emoji='#{emoji}'></div>",
"<span class='award-control-text js-counter'>1</span>",
"</button>"
diff --git a/app/assets/javascripts/compare.js.coffee b/app/assets/javascripts/compare.js.coffee
new file mode 100644
index 00000000000..f20992ead3e
--- /dev/null
+++ b/app/assets/javascripts/compare.js.coffee
@@ -0,0 +1,67 @@
+class @Compare
+ constructor: (@opts) ->
+ @source_loading = $ ".js-source-loading"
+ @target_loading = $ ".js-target-loading"
+
+ $('.js-compare-dropdown').each (i, dropdown) =>
+ $dropdown = $(dropdown)
+
+ $dropdown.glDropdown(
+ selectable: true
+ fieldName: $dropdown.data 'field-name'
+ filterable: true
+ id: (obj, $el) ->
+ $el.data 'id'
+ toggleLabel: (obj, $el) ->
+ $el.text().trim()
+ clicked: (e, el) =>
+ if $dropdown.is '.js-target-branch'
+ @getTargetHtml()
+ else if $dropdown.is '.js-source-branch'
+ @getSourceHtml()
+ else if $dropdown.is '.js-target-project'
+ @getTargetProject()
+ )
+
+ @initialState()
+
+ initialState: ->
+ @getSourceHtml()
+ @getTargetHtml()
+
+ getTargetProject: ->
+ $.ajax(
+ url: @opts.targetProjectUrl
+ data:
+ target_project_id: $("input[name='merge_request[target_project_id]']").val()
+ beforeSend: ->
+ $('.mr_target_commit').empty()
+ success: (html) ->
+ $('.js-target-branch-dropdown .dropdown-content').html html
+ )
+
+ getSourceHtml: ->
+ @sendAjax(@opts.sourceBranchUrl, @source_loading, '.mr_source_commit',
+ ref: $("input[name='merge_request[source_branch]']").val()
+ )
+
+ getTargetHtml: ->
+ @sendAjax(@opts.targetBranchUrl, @target_loading, '.mr_target_commit',
+ target_project_id: $("input[name='merge_request[target_project_id]']").val()
+ ref: $("input[name='merge_request[target_branch]']").val()
+ )
+
+ sendAjax: (url, loading, target, data) ->
+ $target = $(target)
+
+ $.ajax(
+ url: url
+ data: data
+ beforeSend: ->
+ loading.show()
+ $target.empty()
+ success: (html) ->
+ loading.hide()
+ $target.html html
+ $('.js-timeago', $target).timeago()
+ )
diff --git a/app/assets/javascripts/gl_dropdown.js.coffee b/app/assets/javascripts/gl_dropdown.js.coffee
index e8d25591f63..ee1d0fad289 100644
--- a/app/assets/javascripts/gl_dropdown.js.coffee
+++ b/app/assets/javascripts/gl_dropdown.js.coffee
@@ -57,14 +57,30 @@ class GitLabDropdownFilter
filter: (search_text) ->
data = @options.data()
- results = data
- if search_text isnt ""
- results = fuzzaldrinPlus.filter(data, search_text,
- key: @options.keys
- )
+ if data?
+ results = data
- @options.callback results
+ if search_text isnt ''
+ results = fuzzaldrinPlus.filter(data, search_text,
+ key: @options.keys
+ )
+
+ @options.callback results
+ else
+ elements = @options.elements()
+
+ if search_text
+ elements.each ->
+ $el = $(@)
+ matches = fuzzaldrinPlus.match($el.text().trim(), search_text)
+
+ if matches.length
+ $el.show()
+ else
+ $el.hide()
+ else
+ elements.show()
class GitLabDropdownRemote
constructor: (@dataEndpoint, @options) ->
@@ -123,7 +139,7 @@ class GitLabDropdown
if _.isString(@filterInput)
@filterInput = @getElement(@filterInput)
- search_fields = if @options.search then @options.search.fields else [];
+ searchFields = if @options.search then @options.search.fields else [];
if @options.data
# If data is an array
@@ -147,7 +163,14 @@ class GitLabDropdown
filterInputBlur: @filterInputBlur
remote: @options.filterRemote
query: @options.data
- keys: @options.search.fields
+ keys: searchFields
+ elements: =>
+ selector = '.dropdown-content li:not(.divider)'
+
+ if @dropdown.find('.dropdown-toggle-page').length
+ selector = ".dropdown-page-one #{selector}"
+
+ return $(selector)
data: =>
return @fullData
callback: (data) =>
@@ -376,7 +399,7 @@ class GitLabDropdown
# Toggle the dropdown label
if @options.toggleLabel
- $(@el).find(".dropdown-toggle-text").text @options.toggleLabel(selectedObject)
+ $(@el).find(".dropdown-toggle-text").text @options.toggleLabel(selectedObject, el)
if value?
if !field.length and fieldName
# Create hidden input for form
diff --git a/app/assets/javascripts/merge_request_tabs.js.coffee b/app/assets/javascripts/merge_request_tabs.js.coffee
index 0ae6e244602..ef0b534a709 100644
--- a/app/assets/javascripts/merge_request_tabs.js.coffee
+++ b/app/assets/javascripts/merge_request_tabs.js.coffee
@@ -73,7 +73,8 @@ class @MergeRequestTabs
@expandView()
else if action == 'diffs'
@loadDiff($target.attr('href'))
- @shrinkView()
+ if bp? and bp.getBreakpointSize() isnt 'lg'
+ @shrinkView()
else if action == 'builds'
@loadBuilds($target.attr('href'))
@expandView()
diff --git a/app/assets/javascripts/merge_request_widget.js.coffee b/app/assets/javascripts/merge_request_widget.js.coffee
index 7102a0673e9..84a8887fbce 100644
--- a/app/assets/javascripts/merge_request_widget.js.coffee
+++ b/app/assets/javascripts/merge_request_widget.js.coffee
@@ -15,6 +15,8 @@ class @MergeRequestWidget
@pollCIStatus()
notifyPermissions()
+ setOpts: (@opts) ->
+
mergeInProgress: (deleteSourceBranch = false)->
$.ajax
type: 'GET'
@@ -48,7 +50,7 @@ class @MergeRequestWidget
@getCIStatus(true)
@readyForCICheck = false
- ), 5000
+ ), 10000
getCIStatus: (showNotification) ->
_this = @
@@ -61,6 +63,10 @@ class @MergeRequestWidget
@firstCICheck = false
@opts.ci_status = data.status
+ if @opts.ci_status is ''
+ @opts.ci_status = data.status
+ return
+
if data.status isnt @opts.ci_status
@showCIStatus data.status
if data.coverage
diff --git a/app/assets/javascripts/milestone_select.js.coffee b/app/assets/javascripts/milestone_select.js.coffee
index f73127f49f0..6bd4e885a03 100644
--- a/app/assets/javascripts/milestone_select.js.coffee
+++ b/app/assets/javascripts/milestone_select.js.coffee
@@ -85,15 +85,21 @@ class @MilestoneSelect
# display:block overrides the hide-collapse rule
$value.removeAttr('style')
clicked: (selected) ->
+ page = $('body').data 'page'
+ isIssueIndex = page is 'projects:issues:index'
+ isMRIndex = page is page is 'projects:merge_requests:index'
+
if $dropdown.hasClass 'js-filter-bulk-update'
return
- if $dropdown.hasClass('js-filter-submit')
+ if $dropdown.hasClass('js-filter-submit') and (isIssueIndex or isMRIndex)
if selected.name?
selectedMilestone = selected.name
else
selectedMilestone = ''
Issues.filterResults $dropdown.closest('form')
+ else if $dropdown.hasClass('js-filter-submit')
+ $dropdown.closest('form').submit()
else
selected = $selectbox
.find('input[type="hidden"]')
diff --git a/app/assets/javascripts/sidebar.js.coffee b/app/assets/javascripts/sidebar.js.coffee
index e1778511240..860d4f438d0 100644
--- a/app/assets/javascripts/sidebar.js.coffee
+++ b/app/assets/javascripts/sidebar.js.coffee
@@ -4,6 +4,7 @@ expanded = 'page-sidebar-expanded'
toggleSidebar = ->
$('.page-with-sidebar').toggleClass("#{collapsed} #{expanded}")
$('header').toggleClass("header-collapsed header-expanded")
+ $('.toggle-nav-collapse i').toggleClass("fa-angle-right fa-angle-left")
$.cookie("collapsed_nav", $('.page-with-sidebar').hasClass(collapsed), { path: '/' })
setTimeout ( ->
diff --git a/app/assets/javascripts/subscription.js.coffee b/app/assets/javascripts/subscription.js.coffee
index 084f0e0dc65..e4b7a3172ec 100644
--- a/app/assets/javascripts/subscription.js.coffee
+++ b/app/assets/javascripts/subscription.js.coffee
@@ -10,10 +10,10 @@ class @Subscription
btn = $(event.currentTarget)
action = btn.find('span').text()
current_status = @subscription_status.attr('data-status')
- btn.prop('disabled', true)
+ btn.addClass('disabled')
$.post @url, =>
- btn.prop('disabled', false)
+ btn.removeClass('disabled')
status = if current_status == 'subscribed' then 'unsubscribed' else 'subscribed'
@subscription_status.attr('data-status', status)
action = if status == 'subscribed' then 'Unsubscribe' else 'Subscribe'
diff --git a/app/assets/javascripts/todos.js.coffee b/app/assets/javascripts/todos.js.coffee
index ec2df6c5b73..886da72e261 100644
--- a/app/assets/javascripts/todos.js.coffee
+++ b/app/assets/javascripts/todos.js.coffee
@@ -57,5 +57,10 @@ class @Todos
$('.todos-pending .badge, .todos-pending-count').text data.count
$('.todos-done .badge').text data.done_count
- goToTodoUrl: ->
- Turbolinks.visit($(this).data('url'))
+ goToTodoUrl: (e)->
+ todoLink = $(this).data('url')
+ if e.metaKey
+ e.preventDefault()
+ window.open(todoLink,'_blank')
+ else
+ Turbolinks.visit(todoLink)
diff --git a/app/assets/stylesheets/framework/buttons.scss b/app/assets/stylesheets/framework/buttons.scss
index 657c5f033c7..e8c0172680d 100644
--- a/app/assets/stylesheets/framework/buttons.scss
+++ b/app/assets/stylesheets/framework/buttons.scss
@@ -7,6 +7,7 @@
&:focus,
&:active {
outline: none;
+ background-color: $btn-active-gray;
@include box-shadow($gl-btn-active-background);
}
}
@@ -27,7 +28,8 @@
color: $color;
}
- &:active {
+ &:active,
+ &.active {
@include box-shadow ($gl-btn-active-background);
background-color: $dark;
@@ -61,7 +63,7 @@
}
@mixin btn-white {
- @include btn-color($white-light, $border-white-light, $white-normal, $border-white-normal, $white-dark, $border-white-dark, #313236);
+ @include btn-color($white-light, $border-color, $white-normal, $border-white-normal, $white-dark, $border-white-dark, $btn-white-active);
}
.btn {
@@ -218,3 +220,26 @@
margin-right: 5px;
}
}
+
+.btn-text-field {
+ width: 100%;
+ text-align: left;
+ padding: 6px 16px;
+ border-color: $border-color;
+ color: $btn-placeholder-gray;
+ background-color: $background-color;
+
+ &:hover,
+ &:active,
+ &:focus {
+ cursor: text;
+ box-shadow: none;
+ border-color: $border-color;
+ color: $btn-placeholder-gray;
+ background-color: $background-color;
+ }
+}
+
+.btn-file-option {
+ background: linear-gradient(180deg, $white-light 25%, $gray-light 100%);
+}
diff --git a/app/assets/stylesheets/framework/dropdowns.scss b/app/assets/stylesheets/framework/dropdowns.scss
index 82dc1acbd01..ba6c7930cdc 100644
--- a/app/assets/stylesheets/framework/dropdowns.scss
+++ b/app/assets/stylesheets/framework/dropdowns.scss
@@ -248,7 +248,7 @@
.dropdown-title {
position: relative;
- padding: 0 0 15px;
+ padding: 0 25px 15px;
margin: 0 10px 10px;
font-weight: 600;
line-height: 1;
@@ -275,7 +275,7 @@
}
.dropdown-menu-close {
- right: 7px;
+ right: 5px;
width: 20px;
height: 20px;
top: -1px;
diff --git a/app/assets/stylesheets/framework/files.scss b/app/assets/stylesheets/framework/files.scss
index a26ace5cc19..789df42fb66 100644
--- a/app/assets/stylesheets/framework/files.scss
+++ b/app/assets/stylesheets/framework/files.scss
@@ -15,11 +15,13 @@
.file-title {
position: relative;
- background: $background-color;
+ background-color: $background-color;
border-bottom: 1px solid $border-color;
margin: 0;
text-align: left;
padding: 10px $gl-padding;
+ word-wrap: break-word;
+ border-radius: 3px 3px 0 0;
.file-actions {
float: right;
@@ -48,7 +50,7 @@
}
}
- a {
+ a:not(.btn) {
color: $gl-dark-link-color;
}
diff --git a/app/assets/stylesheets/framework/gitlab-theme.scss b/app/assets/stylesheets/framework/gitlab-theme.scss
index fa9038ebaca..c83cf881596 100644
--- a/app/assets/stylesheets/framework/gitlab-theme.scss
+++ b/app/assets/stylesheets/framework/gitlab-theme.scss
@@ -33,15 +33,10 @@
background: $color;
}
- .complex-sidebar .nav-primary {
- border-right: 1px solid lighten($color, 3%);
- }
-
.sidebar-wrapper {
background: $color-darker;
.sidebar-user {
- border-top: 1px solid lighten($color, 3%);
background: $color-darker;
color: $color-light;
@@ -67,6 +62,7 @@
.count {
color: $color-light;
+ background: $color-dark;
}
}
diff --git a/app/assets/stylesheets/framework/header.scss b/app/assets/stylesheets/framework/header.scss
index 724980b2208..b3397d16016 100644
--- a/app/assets/stylesheets/framework/header.scss
+++ b/app/assets/stylesheets/framework/header.scss
@@ -123,11 +123,11 @@ header {
}
@mixin collapsed-header {
- margin-left: 40px;
+ margin-left: $sidebar_collapsed_width;
}
.header-collapsed {
- margin-left: 40px;
+ margin-left: $sidebar_collapsed_width;
@media (min-width: $screen-md-min) {
@include collapsed-header;
diff --git a/app/assets/stylesheets/framework/markdown_area.scss b/app/assets/stylesheets/framework/markdown_area.scss
index ea8e1c902cb..c8f86d60e3b 100644
--- a/app/assets/stylesheets/framework/markdown_area.scss
+++ b/app/assets/stylesheets/framework/markdown_area.scss
@@ -84,6 +84,7 @@
.md-preview-holder {
min-height: 167px;
padding: 10px 0;
+ overflow-x: auto;
}
.markdown-area {
diff --git a/app/assets/stylesheets/framework/sidebar.scss b/app/assets/stylesheets/framework/sidebar.scss
index 1d49249dd80..18189e985c4 100644
--- a/app/assets/stylesheets/framework/sidebar.scss
+++ b/app/assets/stylesheets/framework/sidebar.scss
@@ -144,7 +144,7 @@
}
a {
- padding: 7px 12px;
+ padding: 7px 15px;
font-size: $gl-font-size;
line-height: 24px;
color: $gray;
@@ -169,12 +169,10 @@
}
.count {
- &:before {
- content: '(';
- }
- &:after {
- content: ')';
- }
+ float: right;
+ background: #eee;
+ padding: 0 8px;
+ @include border-radius(6px);
}
&.back-link i {
@@ -193,27 +191,6 @@
}
}
-.expand-nav a {
- color: $gl-icon-color;
- width: 60px;
- position: fixed;
- top: 0;
- left: 0;
- font-size: 20px;
- background: #fff;
- height: 59px;
- text-align: center;
- line-height: 59px;
- border-bottom: 1px solid #eee;
- transition-duration: .3s;
- outline: none;
- z-index: 100;
-
- &:hover {
- text-decoration: none;
- }
-}
-
.collapse-nav a {
width: $sidebar_width;
position: fixed;
@@ -233,12 +210,55 @@
}
.page-sidebar-collapsed {
+ padding-left: $sidebar_collapsed_width;
+
.sidebar-wrapper {
- display: none;
+ width: $sidebar_collapsed_width;
+
+ .header-logo {
+ width: $sidebar_collapsed_width;
+
+ a {
+ padding-left: ($sidebar_collapsed_width - 36) / 2;
+
+ .gitlab-text-container {
+ display: none;
+ }
+ }
+ }
+
+ .nav-sidebar {
+ width: $sidebar_collapsed_width;
+
+ li {
+ width: auto;
+
+ a {
+ span {
+ display: none;
+ }
+ }
+ }
+ }
+
+ .collapse-nav a {
+ width: $sidebar_collapsed_width;
+ }
+
+ .sidebar-user {
+ padding-left: ($sidebar_collapsed_width - 36) / 2;
+ width: $sidebar_collapsed_width;
+
+ .username {
+ display: none;
+ }
+ }
}
}
.page-sidebar-expanded {
+ padding-left: $sidebar_collapsed_width;
+
@media (min-width: $screen-md-min) {
padding-left: $sidebar_width;
}
@@ -289,48 +309,3 @@
padding-right: $sidebar_collapsed_width;
}
}
-
-.complex-sidebar {
- display: inline-block;
-
- .nav-primary {
- width: 61px;
- float: left;
- height: 100vh;
-
- .nav-sidebar {
- width: 60px;
-
- li a {
- width: 60px;
-
- span {
- display: none;
- }
- }
- }
- }
-
- .nav-secondary {
- $nav-secondary-width: 168px;
-
- float: left;
- width: $nav-secondary-width;
-
- .nav-sidebar {
- width: $nav-secondary-width;
-
- li {
- width: $nav-secondary-width;
-
- a {
- width: $nav-secondary-width;
-
- i {
- display: none;
- }
- }
- }
- }
- }
-}
diff --git a/app/assets/stylesheets/framework/timeline.scss b/app/assets/stylesheets/framework/timeline.scss
index aa244fe548d..b91f2f6f898 100644
--- a/app/assets/stylesheets/framework/timeline.scss
+++ b/app/assets/stylesheets/framework/timeline.scss
@@ -14,10 +14,6 @@
background: $row-hover;
}
- &:last-child {
- border-bottom: none;
- }
-
.avatar {
margin-right: 15px;
}
diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss
index 8d3ad934a50..1ebbd9b0e57 100644
--- a/app/assets/stylesheets/framework/variables.scss
+++ b/app/assets/stylesheets/framework/variables.scss
@@ -10,10 +10,10 @@ $gutter_inner_width: 258px;
/*
* UI elements
*/
-$border-color: #efeff1;
+$border-color: #e5e5e5;
$focus-border-color: #3aabf0;
$table-border-color: #eef0f2;
-$background-color: #faf9f9;
+$background-color: #fafafa;
/*
* Text
@@ -81,7 +81,7 @@ $provider-btn-not-active-color: #4688f1;
$white-light: #fff;
$white-normal: #ededed;
-$white-dark: #ededed;
+$white-dark: #ececec;
$gray-light: #faf9f9;
$gray-normal: #f5f5f5;
@@ -108,6 +108,8 @@ $red-light: #e52c5a;
$red-normal: #d22852;
$red-dark: darken($red-normal, 5%);
+$black-transparent: rgba(0, 0, 0, 0.3);
+
$border-white-light: #f1f2f4;
$border-white-normal: #d6dae2;
$border-white-dark: #c6cacf;
@@ -150,15 +152,22 @@ $gl-success: $green-normal;
$gl-info: $blue-normal;
$gl-warning: $orange-normal;
$gl-danger: $red-normal;
-$gl-btn-active-background: rgba(0, 0, 0, 0.12);
-$gl-btn-active-gradient: inset 0 0 4px $gl-btn-active-background;
+$gl-btn-active-background: rgba(0, 0, 0, 0.16);
+$gl-btn-active-gradient: inset 0 2px 3px $gl-btn-active-background;
/*
* Commit Diff Colors
*/
$added: #63c363;
$deleted: #f77;
-
+$line-added: #ecfdf0;
+$line-added-dark: #c7f0d2;
+$line-removed: #fbe9eb;
+$line-removed-dark: #fac5cd;
+$line-number-old: #f9d7dc;
+$line-number-new: #ddfbe6;
+$match-line: #fafafa;
+$table-border-gray: #f0f0f0;
/*
* Fonts
*/
@@ -192,6 +201,13 @@ $dropdown-toggle-icon-color: #c4c4c4;
$dropdown-toggle-hover-icon-color: $dropdown-toggle-hover-border-color;
/*
+* Buttons
+*/
+$btn-active-gray: #ececec;
+$btn-placeholder-gray: #c7c7c7;
+$btn-white-active: #848484;
+
+/*
* Award emoji
*/
$award-emoji-menu-bg: #fff;
diff --git a/app/assets/stylesheets/highlight/solarized_light.scss b/app/assets/stylesheets/highlight/solarized_light.scss
index b90c95c62d1..c482a1258f7 100644
--- a/app/assets/stylesheets/highlight/solarized_light.scss
+++ b/app/assets/stylesheets/highlight/solarized_light.scss
@@ -6,7 +6,7 @@
}
.diff-line-num, .diff-line-num a {
- color: rgba(0, 0, 0, 0.3);
+ color: $black-transparent;
}
// Code itself
@@ -30,7 +30,7 @@
}
.line_content.match {
- color: rgba(0, 0, 0, 0.3);
+ color: $black-transparent;
background: rgba(255, 255, 255, 0.4);
}
}
diff --git a/app/assets/stylesheets/highlight/white.scss b/app/assets/stylesheets/highlight/white.scss
index 8c1b0cd84ec..28331f59754 100644
--- a/app/assets/stylesheets/highlight/white.scss
+++ b/app/assets/stylesheets/highlight/white.scss
@@ -6,12 +6,12 @@
}
.diff-line-num, .diff-line-num a {
- color: rgba(0, 0, 0, 0.3);
+ color: $black-transparent;
}
// Code itself
pre.code, .diff-line-num {
- border-color: $border-color;
+ border-color: $table-border-gray;
}
&, pre.code, .line_holder .line_content {
@@ -23,36 +23,36 @@
.line_holder {
.diff-line-num {
&.old {
- background: #fdd;
- border-color: #f1c0c0;
+ background-color: $line-number-old;
+ border-color: $line-removed-dark;
}
&.new {
- background: #dbffdb;
- border-color: #c1e9c1;
+ background-color: $line-number-new;
+ border-color: $line-added-dark;
}
}
.line_content {
&.old {
- background: #ffecec;
+ background: $line-removed;
span.idiff {
- background-color: #f8cbcb;
+ background-color: $line-removed-dark;
}
}
&.new {
- background: #eaffea;
+ background-color: $line-added;
span.idiff {
- background-color: #a6f3a6;
+ background-color: $line-added-dark;
}
}
&.match {
- color: rgba(0, 0, 0, 0.3);
- background: #fafafa;
+ color: $black-transparent;
+ background: $match-line;
}
}
}
diff --git a/app/assets/stylesheets/pages/commit.scss b/app/assets/stylesheets/pages/commit.scss
index 082911bd118..358d2f4ab9d 100644
--- a/app/assets/stylesheets/pages/commit.scss
+++ b/app/assets/stylesheets/pages/commit.scss
@@ -20,6 +20,8 @@
margin: 0;
padding: 0;
margin-top: 10px;
+ word-break: normal;
+ white-space: pre-wrap;
}
.commit-info-row {
diff --git a/app/assets/stylesheets/pages/commits.scss b/app/assets/stylesheets/pages/commits.scss
index 8272615768d..6453c91d955 100644
--- a/app/assets/stylesheets/pages/commits.scss
+++ b/app/assets/stylesheets/pages/commits.scss
@@ -47,6 +47,7 @@ li.commit {
.commit_short_id {
min-width: 65px;
+ color: $gl-dark-link-color;
font-family: $monospace_font;
}
@@ -88,6 +89,10 @@ li.commit {
padding: 0;
margin: 0;
}
+
+ a {
+ color: $gl-dark-link-color;
+ }
}
.commit-row-info {
diff --git a/app/assets/stylesheets/pages/detail_page.scss b/app/assets/stylesheets/pages/detail_page.scss
index d3eda1a57e6..5917f089720 100644
--- a/app/assets/stylesheets/pages/detail_page.scss
+++ b/app/assets/stylesheets/pages/detail_page.scss
@@ -33,8 +33,12 @@
.description {
margin-top: 6px;
- p:last-child {
- margin-bottom: 0;
+ p {
+ overflow-x: auto;
+
+ &:last-child {
+ margin-bottom: 0;
+ }
}
}
}
diff --git a/app/assets/stylesheets/pages/diff.scss b/app/assets/stylesheets/pages/diff.scss
index f1368d74b3b..d0855f66911 100644
--- a/app/assets/stylesheets/pages/diff.scss
+++ b/app/assets/stylesheets/pages/diff.scss
@@ -2,6 +2,7 @@
.diff-file {
border: 1px solid $border-color;
margin-bottom: $gl-padding;
+ border-radius: 3px;
.diff-header {
position: relative;
@@ -10,6 +11,7 @@
padding: 10px 16px;
color: #555;
z-index: 10;
+ border-radius: 3px 3px 0 0;
.diff-title {
font-family: $monospace_font;
@@ -31,6 +33,7 @@
overflow-y: hidden;
background: #fff;
color: #333;
+ border-radius: 0 0 3px 3px;
.unfold {
cursor: pointer;
@@ -59,9 +62,14 @@
border-collapse: separate;
margin: 0;
padding: 0;
+
.line_holder td {
line-height: $code_line_height;
font-size: $code_font_size;
+
+ span {
+ white-space: pre;
+ }
}
}
@@ -104,6 +112,10 @@
display: table-cell;
}
}
+
+ .text-file.diff-wrap-lines table .line_holder td span {
+ white-space: pre-wrap;
+ }
}
.image {
background: #ddd;
@@ -316,6 +328,16 @@
float: right;
}
+.diffs {
+ .content-block {
+ border-bottom: none;
+ }
+}
+
+.files-changed {
+ border-bottom: none;
+}
+
// Mobile
@media (max-width: 480px) {
.diff-title {
diff --git a/app/assets/stylesheets/pages/help.scss b/app/assets/stylesheets/pages/help.scss
index bd224705f04..604f1700cf8 100644
--- a/app/assets/stylesheets/pages/help.scss
+++ b/app/assets/stylesheets/pages/help.scss
@@ -59,6 +59,9 @@
position: relative;
overflow-y: auto;
padding: 15px;
+ .form-actions {
+ margin: -$gl-padding+1;
+ }
}
body.modal-open {
diff --git a/app/assets/stylesheets/pages/labels.scss b/app/assets/stylesheets/pages/labels.scss
index 4e02ec4e891..3e0a3140be7 100644
--- a/app/assets/stylesheets/pages/labels.scss
+++ b/app/assets/stylesheets/pages/labels.scss
@@ -49,6 +49,15 @@
}
.label-row {
+ .label-name {
+ display: inline-block;
+ width: 200px;
+
+ @media (max-width: $screen-xs-min) {
+ display: block;
+ }
+ }
+
.label {
padding: 9px;
font-size: 14px;
@@ -69,3 +78,52 @@
background-color: $gl-danger;
color: $white-light;
}
+
+.manage-labels-list {
+
+ .prepend-left-10 {
+ display: inline-block;
+ width: 40%;
+ vertical-align: middle;
+
+ @media (max-width: $screen-xs-min) {
+ display: block;
+ width: 100%;
+ margin-left: 0;
+ padding: 10px 0;
+ }
+ }
+
+ .pull-info-right {
+ float: right;
+
+ @media (max-width: $screen-xs-min) {
+ float: none;
+ }
+
+ .action-buttons {
+ border-color: transparent;
+ padding: 6px;
+ color: $gl-text-color;
+
+ &.subscribe-button {
+ padding-left: 0;
+ }
+ }
+
+ i {
+ color: $gl-text-color;
+ }
+
+ .append-right-20 {
+ a {
+ color: $gl-text-color;
+ }
+
+ @media (max-width: $screen-xs-min) {
+ display: block;
+ margin-bottom: 10px;
+ }
+ }
+ }
+}
diff --git a/app/assets/stylesheets/pages/merge_requests.scss b/app/assets/stylesheets/pages/merge_requests.scss
index 1c6a4208974..b79335eab91 100644
--- a/app/assets/stylesheets/pages/merge_requests.scss
+++ b/app/assets/stylesheets/pages/merge_requests.scss
@@ -123,6 +123,8 @@
.mr_source_commit,
.mr_target_commit {
+ margin-bottom: 0;
+
.commit {
margin: 0;
padding: 2px 0;
@@ -174,10 +176,6 @@
display: none;
}
-.merge-request-form .select2-container {
- width: 250px !important;
-}
-
#modal_merge_info .modal-dialog {
width: 600px;
@@ -200,3 +198,76 @@
overflow-x: scroll;
}
}
+
+.panel-new-merge-request {
+ .panel-heading {
+ padding: 5px 10px;
+ font-weight: 600;
+ line-height: 25px;
+ }
+
+ .panel-body {
+ padding: 10px 5px;
+ }
+
+ .panel-footer {
+ padding: 5px 10px;
+ }
+
+ .commit {
+ .commit-row-title {
+ margin-bottom: 4px;
+ }
+
+ .avatar {
+ width: 20px;
+ height: 20px;
+ margin-right: 5px;
+ }
+
+ .commit-row-info {
+ line-height: 20px;
+ }
+ }
+
+ .btn-clipboard {
+ margin-right: 5px;
+ padding: 0;
+ background: transparent;
+ }
+
+ .ci-status-link {
+ margin-right: 5px;
+ }
+}
+
+.merge-request-select {
+ padding-left: 5px;
+ padding-right: 5px;
+ margin-bottom: 10px;
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+
+ @media (min-width: $screen-sm-min) {
+ float: left;
+ width: 50%;
+ margin-bottom: 0;
+ }
+
+ .dropdown-menu-toggle {
+ width: 100%;
+ }
+
+ .dropdown-menu {
+ left: 5px;
+ right: 5px;
+ width: auto;
+ }
+}
+
+.issuable-form-select-holder {
+ display: inline-block;
+ width: 250px;
+}
diff --git a/app/assets/stylesheets/pages/note_form.scss b/app/assets/stylesheets/pages/note_form.scss
index a909776b437..4d4d508396d 100644
--- a/app/assets/stylesheets/pages/note_form.scss
+++ b/app/assets/stylesheets/pages/note_form.scss
@@ -1,10 +1,10 @@
/**
* Note Form
*/
-.reply-btn {
- @extend .btn-primary;
- margin: 10px $gl-padding;
+.comment-btn {
+ @extend .btn-create;
}
+
.diff-file .diff-content {
tr.line_holder:hover > td .line_note_link {
opacity: 1.0;
@@ -113,13 +113,12 @@
.discussion-body,
.diff-file {
.notes .note {
- border-color: #ddd;
padding: 10px 15px;
}
.discussion-reply-holder {
- background: $background-color;
- border-top: 1px solid $border-color;
+ background-color: $white-light;
+ padding: 10px 16px;
}
}
diff --git a/app/assets/stylesheets/pages/notes.scss b/app/assets/stylesheets/pages/notes.scss
index 614ca48b901..7295fe51121 100644
--- a/app/assets/stylesheets/pages/notes.scss
+++ b/app/assets/stylesheets/pages/notes.scss
@@ -58,6 +58,7 @@ ul.notes {
.note {
display: block;
position: relative;
+ border-bottom: 1px solid $table-border-gray;
&.is-editting {
.note-header,
@@ -82,7 +83,7 @@ ul.notes {
// On diffs code should wrap nicely and not overflow
pre {
code {
- white-space: pre-wrap;
+ white-space: pre;
}
}
@@ -117,9 +118,6 @@ ul.notes {
padding-bottom: 3px;
}
- &:last-child {
- border-bottom: 1px solid $border-color;
- }
}
}
@@ -137,14 +135,14 @@ ul.notes {
font-family: $regular_font;
td {
- border: 1px solid #ddd;
+ border: 1px solid $table-border-gray;
border-left: none;
&.notes_line {
vertical-align: middle;
text-align: center;
padding: 10px 0;
- background: #fff;
+ background: $background-color;
color: $text-color;
}
&.notes_line2 {
@@ -175,9 +173,6 @@ ul.notes {
}
}
- .author_link {
- font-weight: 600;
- }
}
.note-headline-light,
@@ -203,14 +198,26 @@ ul.notes {
line-height: 24px;
.fa {
+ color: $notes-action-color;
position: relative;
top: 1px;
font-size: 17px;
}
- .fa-trash-o {
- top: 0;
- font-size: 16px;
+ &.js-note-delete {
+ i {
+ &:hover {
+ color: $gl-text-red;
+ }
+ }
+ }
+
+ &.js-note-edit {
+ i {
+ &:hover {
+ color: $gl-link-color;
+ }
+ }
}
}
diff --git a/app/controllers/admin/projects_controller.rb b/app/controllers/admin/projects_controller.rb
index 4089091d569..c6b3105544a 100644
--- a/app/controllers/admin/projects_controller.rb
+++ b/app/controllers/admin/projects_controller.rb
@@ -5,7 +5,7 @@ class Admin::ProjectsController < Admin::ApplicationController
def index
@projects = Project.all
@projects = @projects.in_namespace(params[:namespace_id]) if params[:namespace_id].present?
- @projects = @projects.where("visibility_level IN (?)", params[:visibility_levels]) if params[:visibility_levels].present?
+ @projects = @projects.where("projects.visibility_level IN (?)", params[:visibility_levels]) if params[:visibility_levels].present?
@projects = @projects.with_push if params[:with_push].present?
@projects = @projects.abandoned if params[:abandoned].present?
@projects = @projects.non_archived unless params[:with_archived].present?
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index c81cb85dc1b..97d53acde94 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -47,6 +47,16 @@ class ApplicationController < ActionController::Base
email: current_user.email,
username: current_user.username,
)
+
+ Raven.tags_context(program: sentry_program_context)
+ end
+ end
+
+ def sentry_program_context
+ if Sidekiq.server?
+ 'sidekiq'
+ else
+ 'rails'
end
end
diff --git a/app/controllers/groups/milestones_controller.rb b/app/controllers/groups/milestones_controller.rb
index b23c3022fb5..9d5a28e8d4d 100644
--- a/app/controllers/groups/milestones_controller.rb
+++ b/app/controllers/groups/milestones_controller.rb
@@ -18,14 +18,14 @@ class Groups::MilestonesController < Groups::ApplicationController
end
def create
- project_ids = params[:milestone][:project_ids]
+ project_ids = params[:milestone][:project_ids].reject(&:blank?)
title = milestone_params[:title]
- @projects.where(id: project_ids).each do |project|
- Milestones::CreateService.new(project, current_user, milestone_params).execute
+ if create_milestones(project_ids)
+ redirect_to milestone_path(title)
+ else
+ render_new_with_error(project_ids.empty?)
end
-
- redirect_to milestone_path(title)
end
def show
@@ -41,6 +41,27 @@ class Groups::MilestonesController < Groups::ApplicationController
private
+ def create_milestones(project_ids)
+ return false unless project_ids.present?
+
+ ActiveRecord::Base.transaction do
+ @projects.where(id: project_ids).each do |project|
+ Milestones::CreateService.new(project, current_user, milestone_params).execute
+ end
+ end
+
+ true
+ rescue ActiveRecord::ActiveRecordError => e
+ flash.now[:alert] = "An error occurred while creating the milestone: #{e.message}"
+ false
+ end
+
+ def render_new_with_error(empty_project_ids)
+ @milestone = Milestone.new(milestone_params)
+ @milestone.errors.add(:project_id, "Please select at least one project.") if empty_project_ids
+ render :new
+ end
+
def authorize_admin_milestones!
return render_404 unless can?(current_user, :admin_milestones, group)
end
diff --git a/app/controllers/omniauth_callbacks_controller.rb b/app/controllers/omniauth_callbacks_controller.rb
index 21135f7d607..d28e96c3f18 100644
--- a/app/controllers/omniauth_callbacks_controller.rb
+++ b/app/controllers/omniauth_callbacks_controller.rb
@@ -55,7 +55,7 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
end
else
saml_user = Gitlab::Saml::User.new(oauth)
- saml_user.save
+ saml_user.save if saml_user.changed?
@user = saml_user.gl_user
continue_login_process
diff --git a/app/controllers/projects/application_controller.rb b/app/controllers/projects/application_controller.rb
index 657ee94cfd7..74150ad606b 100644
--- a/app/controllers/projects/application_controller.rb
+++ b/app/controllers/projects/application_controller.rb
@@ -68,7 +68,9 @@ class Projects::ApplicationController < ApplicationController
end
def require_non_empty_project
- redirect_to namespace_project_path(@project.namespace, @project) if @project.empty_repo?
+ # Be sure to return status code 303 to avoid a double DELETE:
+ # http://api.rubyonrails.org/classes/ActionController/Redirecting.html
+ redirect_to namespace_project_path(@project.namespace, @project), status: 303 if @project.empty_repo?
end
def require_branch_head
diff --git a/app/controllers/projects/badges_controller.rb b/app/controllers/projects/badges_controller.rb
index 6d4d4360988..824aa41db51 100644
--- a/app/controllers/projects/badges_controller.rb
+++ b/app/controllers/projects/badges_controller.rb
@@ -1,5 +1,12 @@
class Projects::BadgesController < Projects::ApplicationController
- before_action :no_cache_headers
+ layout 'project_settings'
+ before_action :authorize_admin_project!, only: [:index]
+ before_action :no_cache_headers, except: [:index]
+
+ def index
+ @ref = params[:ref] || @project.default_branch || 'master'
+ @build_badge = Gitlab::Badge::Build.new(@project, @ref)
+ end
def build
badge = Gitlab::Badge::Build.new(project, params[:ref])
diff --git a/app/controllers/projects/branches_controller.rb b/app/controllers/projects/branches_controller.rb
index c0a53734921..d09e7375b67 100644
--- a/app/controllers/projects/branches_controller.rb
+++ b/app/controllers/projects/branches_controller.rb
@@ -48,7 +48,7 @@ class Projects::BranchesController < Projects::ApplicationController
respond_to do |format|
format.html do
redirect_to namespace_project_branches_path(@project.namespace,
- @project)
+ @project), status: 303
end
format.js { render status: status[:return_code] }
end
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index 49064f5d505..ae613f5e093 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -207,20 +207,20 @@ class Projects::MergeRequestsController < Projects::ApplicationController
#This is always source
@source_project = @merge_request.nil? ? @project : @merge_request.source_project
@commit = @repository.commit(params[:ref]) if params[:ref].present?
+ render layout: false
end
def branch_to
@target_project = selected_target_project
@commit = @target_project.commit(params[:ref]) if params[:ref].present?
+ render layout: false
end
def update_branches
@target_project = selected_target_project
@target_branches = @target_project.repository.branch_names
- respond_to do |format|
- format.js
- end
+ render layout: false
end
def ci_status
diff --git a/app/controllers/projects/refs_controller.rb b/app/controllers/projects/refs_controller.rb
index 00df1c9c965..d79f16e6a5a 100644
--- a/app/controllers/projects/refs_controller.rb
+++ b/app/controllers/projects/refs_controller.rb
@@ -24,6 +24,8 @@ class Projects::RefsController < Projects::ApplicationController
namespace_project_find_file_path(@project.namespace, @project, @id)
when "graphs_commits"
commits_namespace_project_graph_path(@project.namespace, @project, @id)
+ when "badges"
+ namespace_project_badges_path(@project.namespace, @project, ref: @id)
else
namespace_project_commits_path(@project.namespace, @project, @id)
end
diff --git a/app/controllers/projects/wikis_controller.rb b/app/controllers/projects/wikis_controller.rb
index 02ceb8f4334..9f3a4a69721 100644
--- a/app/controllers/projects/wikis_controller.rb
+++ b/app/controllers/projects/wikis_controller.rb
@@ -88,6 +88,20 @@ class Projects::WikisController < Projects::ApplicationController
)
end
+ def markdown_preview
+ text = params[:text]
+
+ ext = Gitlab::ReferenceExtractor.new(@project, current_user, current_user)
+ ext.analyze(text)
+
+ render json: {
+ body: view_context.markdown(text, pipeline: :wiki, project_wiki: @project_wiki),
+ references: {
+ users: ext.users.map(&:username)
+ }
+ }
+ end
+
def git_access
end
diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb
index 65677a3dd3c..c29f4609e93 100644
--- a/app/controllers/sessions_controller.rb
+++ b/app/controllers/sessions_controller.rb
@@ -5,7 +5,8 @@ class SessionsController < Devise::SessionsController
skip_before_action :check_2fa_requirement, only: [:destroy]
prepend_before_action :check_initial_setup, only: [:new]
- prepend_before_action :authenticate_with_two_factor, only: [:create]
+ prepend_before_action :authenticate_with_two_factor,
+ if: :two_factor_enabled?, only: [:create]
prepend_before_action :store_redirect_path, only: [:new]
before_action :auto_sign_in_with_provider, only: [:new]
@@ -56,10 +57,10 @@ class SessionsController < Devise::SessionsController
end
def find_user
- if user_params[:login]
- User.by_login(user_params[:login])
- elsif user_params[:otp_attempt] && session[:otp_user_id]
+ if session[:otp_user_id]
User.find(session[:otp_user_id])
+ elsif user_params[:login]
+ User.by_login(user_params[:login])
end
end
@@ -83,11 +84,13 @@ class SessionsController < Devise::SessionsController
end
end
+ def two_factor_enabled?
+ find_user.try(:two_factor_enabled?)
+ end
+
def authenticate_with_two_factor
user = self.resource = find_user
- return unless user && user.two_factor_enabled?
-
if user_params[:otp_attempt].present? && session[:otp_user_id]
if valid_otp_attempt?(user)
# Remove any lingering user data from login
diff --git a/app/helpers/blob_helper.rb b/app/helpers/blob_helper.rb
index 820d69c230b..9e59a295fc4 100644
--- a/app/helpers/blob_helper.rb
+++ b/app/helpers/blob_helper.rb
@@ -27,9 +27,9 @@ module BlobHelper
link_opts)
if !on_top_of_branch?(project, ref)
- button_tag "Edit", class: "btn btn-default disabled has-tooltip", title: "You can only edit files when you are on a branch", data: { container: 'body' }
+ button_tag "Edit", class: "btn disabled has-tooltip btn-file-option", title: "You can only edit files when you are on a branch", data: { container: 'body' }
elsif can_edit_blob?(blob, project, ref)
- link_to "Edit", edit_path, class: 'btn'
+ link_to "Edit", edit_path, class: 'btn btn-file-option'
elsif can?(current_user, :fork_project, project)
continue_params = {
to: edit_path,
@@ -38,7 +38,7 @@ module BlobHelper
}
fork_path = namespace_project_forks_path(project.namespace, project, namespace_key: current_user.namespace.id, continue: continue_params)
- link_to "Edit", fork_path, class: 'btn', method: :post
+ link_to "Edit", fork_path, class: 'btn btn-file-option', method: :post
end
end
diff --git a/app/helpers/commits_helper.rb b/app/helpers/commits_helper.rb
index bde0799f3de..35ba543cef1 100644
--- a/app/helpers/commits_helper.rb
+++ b/app/helpers/commits_helper.rb
@@ -28,7 +28,7 @@ module CommitsHelper
def commit_to_html(commit, project, inline = true)
template = inline ? "inline_commit" : "commit"
- escape_javascript(render "projects/commits/#{template}", commit: commit, project: project) unless commit.nil?
+ render "projects/commits/#{template}", commit: commit, project: project unless commit.nil?
end
# Breadcrumb links for a Project and, if applicable, a tree path
@@ -117,7 +117,7 @@ module CommitsHelper
end
end
link_to(
- "Browse Files »",
+ "Browse Files",
namespace_project_tree_path(project.namespace, project, commit),
class: "pull-right"
)
@@ -197,7 +197,7 @@ module CommitsHelper
link_to(
namespace_project_blob_path(project.namespace, project,
tree_join(commit_sha, diff.new_path)),
- class: 'btn view-file js-view-file'
+ class: 'btn view-file js-view-file btn-file-option'
) do
raw('View file @') + content_tag(:span, commit_sha[0..6],
class: 'commit-short-id')
diff --git a/app/helpers/form_helper.rb b/app/helpers/form_helper.rb
new file mode 100644
index 00000000000..6a43be2cf3e
--- /dev/null
+++ b/app/helpers/form_helper.rb
@@ -0,0 +1,18 @@
+module FormHelper
+ def form_errors(model)
+ return unless model.errors.any?
+
+ pluralized = 'error'.pluralize(model.errors.count)
+ headline = "The form contains the following #{pluralized}:"
+
+ content_tag(:div, class: 'alert alert-danger', id: 'error_explanation') do
+ content_tag(:h4, headline) <<
+ content_tag(:ul) do
+ model.errors.full_messages.
+ map { |msg| content_tag(:li, msg) }.
+ join.
+ html_safe
+ end
+ end
+ end
+end
diff --git a/app/helpers/gitlab_markdown_helper.rb b/app/helpers/gitlab_markdown_helper.rb
index 2f760af02fd..3a45205563e 100644
--- a/app/helpers/gitlab_markdown_helper.rb
+++ b/app/helpers/gitlab_markdown_helper.rb
@@ -116,29 +116,6 @@ module GitlabMarkdownHelper
end
end
- MARKDOWN_TIPS = [
- "End a line with two or more spaces for a line-break, or soft-return",
- "Inline code can be denoted by `surrounding it with backticks`",
- "Blocks of code can be denoted by three backticks ``` or four leading spaces",
- "Emoji can be added by :emoji_name:, for example :thumbsup:",
- "Notify other participants using @user_name",
- "Notify a specific group using @group_name",
- "Notify the entire team using @all",
- "Reference an issue using a hash, for example issue #123",
- "Reference a merge request using an exclamation point, for example MR !123",
- "Italicize words or phrases using *asterisks* or _underscores_",
- "Bold words or phrases using **double asterisks** or __double underscores__",
- "Strikethrough words or phrases using ~~two tildes~~",
- "Make a bulleted list using + pluses, - minuses, or * asterisks",
- "Denote blockquotes using > at the beginning of a line",
- "Make a horizontal line using three or more hyphens ---, asterisks ***, or underscores ___"
- ].freeze
-
- # Returns a random markdown tip for use as a textarea placeholder
- def random_markdown_tip
- MARKDOWN_TIPS.sample
- end
-
private
# Return +text+, truncated to +max_chars+ characters, excluding any HTML
diff --git a/app/helpers/issues_helper.rb b/app/helpers/issues_helper.rb
index 24b90fef4fe..bcf8639c829 100644
--- a/app/helpers/issues_helper.rb
+++ b/app/helpers/issues_helper.rb
@@ -115,17 +115,32 @@ module IssuesHelper
icon('eye-slash') if issue.confidential?
end
- def emoji_icon(name, unicode = nil, aliases = [])
+ def emoji_icon(name, unicode = nil, aliases = [], sprite: true)
unicode ||= Emoji.emoji_filename(name) rescue ""
- content_tag :div, "",
- class: "icon emoji-icon emoji-#{unicode}",
- title: name,
- data: {
- aliases: aliases.join(' '),
- emoji: name,
- unicode_name: unicode
- }
+ data = {
+ aliases: aliases.join(" "),
+ emoji: name,
+ unicode_name: unicode
+ }
+
+ if sprite
+ # Emoji icons for the emoji menu, these use a spritesheet.
+ content_tag :div, "",
+ class: "icon emoji-icon emoji-#{unicode}",
+ title: name,
+ data: data
+ else
+ # Emoji icons displayed separately, used for the awards already given
+ # to an issue or merge request.
+ content_tag :img, "",
+ class: "icon emoji",
+ title: name,
+ height: "20px",
+ width: "20px",
+ src: url_to_image("#{unicode}.png"),
+ data: data
+ end
end
def emoji_author_list(notes, current_user)
diff --git a/app/helpers/notes_helper.rb b/app/helpers/notes_helper.rb
index 698f90cb27a..95072b5373f 100644
--- a/app/helpers/notes_helper.rb
+++ b/app/helpers/notes_helper.rb
@@ -69,10 +69,7 @@ module NotesHelper
line_type: line_type
}
- button_tag class: 'btn btn-nr reply-btn js-discussion-reply-button',
- data: data, title: 'Add a reply' do
- link_text = icon('comment')
- link_text << ' Reply'
- end
+ button_tag 'Reply...', class: 'btn btn-text-field js-discussion-reply-button',
+ data: data, title: 'Add a reply'
end
end
diff --git a/app/models/repository.rb b/app/models/repository.rb
index a8e826c9cbf..8dead3a5884 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -331,6 +331,8 @@ class Repository
# Runs code after a repository has been created.
def after_create
expire_exists_cache
+ expire_root_ref_cache
+ expire_emptiness_caches
end
# Runs code just before a repository is deleted.
diff --git a/app/services/git_push_service.rb b/app/services/git_push_service.rb
index 36c9ee92da1..dc74c02760b 100644
--- a/app/services/git_push_service.rb
+++ b/app/services/git_push_service.rb
@@ -55,15 +55,15 @@ class GitPushService < BaseService
end
def update_main_language
+ # Performance can be bad so for now only check main_language once
+ # See https://gitlab.com/gitlab-org/gitlab-ce/issues/14937
+ return if @project.main_language.present?
+
return unless is_default_branch?
return unless push_to_new_branch? || push_to_existing_branch?
current_language = @project.repository.main_language
-
- unless current_language == @project.main_language
- return @project.update_attributes(main_language: current_language)
- end
-
+ @project.update_attributes(main_language: current_language)
true
end
diff --git a/app/services/milestones/create_service.rb b/app/services/milestones/create_service.rb
index b8e08c9f1eb..3b90399af64 100644
--- a/app/services/milestones/create_service.rb
+++ b/app/services/milestones/create_service.rb
@@ -3,7 +3,7 @@ module Milestones
def execute
milestone = project.milestones.new(params)
- if milestone.save
+ if milestone.save!
event_service.open_milestone(milestone, current_user)
end
diff --git a/app/views/abuse_reports/new.html.haml b/app/views/abuse_reports/new.html.haml
index 3bc1b24b5e2..06be1a53318 100644
--- a/app/views/abuse_reports/new.html.haml
+++ b/app/views/abuse_reports/new.html.haml
@@ -3,11 +3,9 @@
%p Please use this form to report users who create spam issues, comments or behave inappropriately.
%hr
= form_for @abuse_report, html: { class: 'form-horizontal js-quick-submit js-requires-input'} do |f|
+ = form_errors(@abuse_report)
+
= f.hidden_field :user_id
- - if @abuse_report.errors.any?
- .alert.alert-danger
- - @abuse_report.errors.full_messages.each do |msg|
- %p= msg
.form-group
= f.label :user_id, class: 'control-label'
.col-sm-10
diff --git a/app/views/admin/appearances/_form.html.haml b/app/views/admin/appearances/_form.html.haml
index 6f325914d14..d88f3ad314d 100644
--- a/app/views/admin/appearances/_form.html.haml
+++ b/app/views/admin/appearances/_form.html.haml
@@ -1,8 +1,5 @@
= form_for @appearance, url: admin_appearances_path, html: { class: 'form-horizontal'} do |f|
- - if @appearance.errors.any?
- .alert.alert-danger
- - @appearance.errors.full_messages.each do |msg|
- %p= msg
+ = form_errors(@appearance)
%fieldset.sign-in
%legend
diff --git a/app/views/admin/application_settings/_form.html.haml b/app/views/admin/application_settings/_form.html.haml
index de86dacbb12..a8cca1a81cb 100644
--- a/app/views/admin/application_settings/_form.html.haml
+++ b/app/views/admin/application_settings/_form.html.haml
@@ -1,9 +1,5 @@
= form_for @application_setting, url: admin_application_settings_path, html: { class: 'form-horizontal fieldset-form' } do |f|
- - if @application_setting.errors.any?
- #error_explanation
- .alert.alert-danger
- - @application_setting.errors.full_messages.each do |msg|
- %p= msg
+ = form_errors(@application_setting)
%fieldset
%legend Visibility and Access Controls
diff --git a/app/views/admin/applications/_form.html.haml b/app/views/admin/applications/_form.html.haml
index e18f7b499dd..4aacbb8cd77 100644
--- a/app/views/admin/applications/_form.html.haml
+++ b/app/views/admin/applications/_form.html.haml
@@ -1,9 +1,6 @@
= form_for [:admin, @application], url: @url, html: {class: 'form-horizontal', role: 'form'} do |f|
- - if application.errors.any?
- .alert.alert-danger
- %button{ type: "button", class: "close", "data-dismiss" => "alert"} &times;
- - application.errors.full_messages.each do |msg|
- %p= msg
+ = form_errors(application)
+
= content_tag :div, class: 'form-group' do
= f.label :name, class: 'col-sm-2 control-label'
.col-sm-10
diff --git a/app/views/admin/broadcast_messages/_form.html.haml b/app/views/admin/broadcast_messages/_form.html.haml
index b748460a9f7..6b157abf842 100644
--- a/app/views/admin/broadcast_messages/_form.html.haml
+++ b/app/views/admin/broadcast_messages/_form.html.haml
@@ -4,10 +4,8 @@
= render_broadcast_message(@broadcast_message.message.presence || "Your message here")
= form_for [:admin, @broadcast_message], html: { class: 'broadcast-message-form form-horizontal js-quick-submit js-requires-input'} do |f|
- -if @broadcast_message.errors.any?
- .alert.alert-danger
- - @broadcast_message.errors.full_messages.each do |msg|
- %p= msg
+ = form_errors(@broadcast_message)
+
.form-group
= f.label :message, class: 'control-label'
.col-sm-10
diff --git a/app/views/admin/deploy_keys/new.html.haml b/app/views/admin/deploy_keys/new.html.haml
index 5b46b3222a9..15aa059c93d 100644
--- a/app/views/admin/deploy_keys/new.html.haml
+++ b/app/views/admin/deploy_keys/new.html.haml
@@ -4,11 +4,7 @@
%div
= form_for [:admin, @deploy_key], html: { class: 'deploy-key-form form-horizontal' } do |f|
- -if @deploy_key.errors.any?
- .alert.alert-danger
- %ul
- - @deploy_key.errors.full_messages.each do |msg|
- %li= msg
+ = form_errors(@deploy_key)
.form-group
= f.label :title, class: "control-label"
diff --git a/app/views/admin/groups/_form.html.haml b/app/views/admin/groups/_form.html.haml
index 7f2b1cd235d..0cc405401cf 100644
--- a/app/views/admin/groups/_form.html.haml
+++ b/app/views/admin/groups/_form.html.haml
@@ -1,8 +1,5 @@
= form_for [:admin, @group], html: { class: "form-horizontal" } do |f|
- - if @group.errors.any?
- .alert.alert-danger
- %span= @group.errors.full_messages.first
-
+ = form_errors(@group)
= render 'shared/group_form', f: f
.form-group.group-description-holder
diff --git a/app/views/admin/hooks/index.html.haml b/app/views/admin/hooks/index.html.haml
index 53b3cd04c68..ad952052f25 100644
--- a/app/views/admin/hooks/index.html.haml
+++ b/app/views/admin/hooks/index.html.haml
@@ -10,10 +10,8 @@
= form_for @hook, as: :hook, url: admin_hooks_path, html: { class: 'form-horizontal' } do |f|
- -if @hook.errors.any?
- .alert.alert-danger
- - @hook.errors.full_messages.each do |msg|
- %p= msg
+ = form_errors(@hook)
+
.form-group
= f.label :url, "URL:", class: 'control-label'
.col-sm-10
diff --git a/app/views/admin/identities/_form.html.haml b/app/views/admin/identities/_form.html.haml
index 3a788558226..112a201fafa 100644
--- a/app/views/admin/identities/_form.html.haml
+++ b/app/views/admin/identities/_form.html.haml
@@ -1,9 +1,5 @@
= form_for [:admin, @user, @identity], html: { class: 'form-horizontal fieldset-form' } do |f|
- - if @identity.errors.any?
- #error_explanation
- .alert.alert-danger
- - @identity.errors.full_messages.each do |msg|
- %p= msg
+ = form_errors(@identity)
.form-group
= f.label :provider, class: 'control-label'
diff --git a/app/views/admin/labels/_form.html.haml b/app/views/admin/labels/_form.html.haml
index 8c6b389bf15..448aa953548 100644
--- a/app/views/admin/labels/_form.html.haml
+++ b/app/views/admin/labels/_form.html.haml
@@ -1,11 +1,5 @@
= form_for [:admin, @label], html: { class: 'form-horizontal label-form js-requires-input' } do |f|
- -if @label.errors.any?
- .row
- .col-sm-offset-2.col-sm-10
- .alert.alert-danger
- - @label.errors.full_messages.each do |msg|
- %span= msg
- %br
+ = form_errors(@label)
.form-group
= f.label :title, class: 'control-label'
diff --git a/app/views/admin/users/_form.html.haml b/app/views/admin/users/_form.html.haml
index d2527ede995..b05fdbd5552 100644
--- a/app/views/admin/users/_form.html.haml
+++ b/app/views/admin/users/_form.html.haml
@@ -1,10 +1,6 @@
.user_new
= form_for [:admin, @user], html: { class: 'form-horizontal fieldset-form' } do |f|
- -if @user.errors.any?
- #error_explanation
- .alert.alert-danger
- - @user.errors.full_messages.each do |msg|
- %p= msg
+ = form_errors(@user)
%fieldset
%legend Account
diff --git a/app/views/doorkeeper/applications/_form.html.haml b/app/views/doorkeeper/applications/_form.html.haml
index 906b0676150..5c98265727a 100644
--- a/app/views/doorkeeper/applications/_form.html.haml
+++ b/app/views/doorkeeper/applications/_form.html.haml
@@ -1,9 +1,5 @@
= form_for application, url: doorkeeper_submit_path(application), html: {role: 'form'} do |f|
- - if application.errors.any?
- .alert.alert-danger
- %ul
- - application.errors.full_messages.each do |msg|
- %li= msg
+ = form_errors(application)
.form-group
= f.label :name, class: 'label-light'
diff --git a/app/views/groups/edit.html.haml b/app/views/groups/edit.html.haml
index ea5a0358392..a698cbbe9db 100644
--- a/app/views/groups/edit.html.haml
+++ b/app/views/groups/edit.html.haml
@@ -5,9 +5,7 @@
Group settings
.panel-body
= form_for @group, html: { multipart: true, class: "form-horizontal" }, authenticity_token: true do |f|
- - if @group.errors.any?
- .alert.alert-danger
- %span= @group.errors.full_messages.first
+ = form_errors(@group)
= render 'shared/group_form', f: f
.form-group
diff --git a/app/views/groups/milestones/new.html.haml b/app/views/groups/milestones/new.html.haml
index a8e1ed77da9..4290e0bf72e 100644
--- a/app/views/groups/milestones/new.html.haml
+++ b/app/views/groups/milestones/new.html.haml
@@ -10,6 +10,14 @@
= form_for @milestone, url: group_milestones_path(@group), html: { class: 'form-horizontal milestone-form gfm-form js-quick-submit js-requires-input' } do |f|
.row
+ - if @milestone.errors.any?
+ #error_explanation
+ .alert.alert-danger
+ %ul
+ - @milestone.errors.full_messages.each do |msg|
+ %li
+ = msg
+
.col-md-6
.form-group
= f.label :title, "Title", class: "control-label"
diff --git a/app/views/groups/new.html.haml b/app/views/groups/new.html.haml
index 30ab8aeba13..2b8bc269e64 100644
--- a/app/views/groups/new.html.haml
+++ b/app/views/groups/new.html.haml
@@ -6,10 +6,7 @@
%hr
= form_for @group, html: { class: 'group-form form-horizontal' } do |f|
- - if @group.errors.any?
- .alert.alert-danger
- %span= @group.errors.full_messages.first
-
+ = form_errors(@group)
= render 'shared/group_form', f: f, autofocus: true
.form-group.group-description-holder
diff --git a/app/views/layouts/_collapse_button.html.haml b/app/views/layouts/_collapse_button.html.haml
new file mode 100644
index 00000000000..2ed51d87ca1
--- /dev/null
+++ b/app/views/layouts/_collapse_button.html.haml
@@ -0,0 +1,4 @@
+- if nav_menu_collapsed?
+ = link_to icon('angle-right'), '#', class: 'toggle-nav-collapse', title: "Open/Close"
+- else
+ = link_to icon('angle-left'), '#', class: 'toggle-nav-collapse', title: "Open/Close"
diff --git a/app/views/layouts/_page.html.haml b/app/views/layouts/_page.html.haml
index 9be36273c7d..c799e9c588d 100644
--- a/app/views/layouts/_page.html.haml
+++ b/app/views/layouts/_page.html.haml
@@ -1,7 +1,5 @@
.page-with-sidebar{ class: "#{page_sidebar_class} #{page_gutter_class}" }
= render "layouts/broadcast"
- .expand-nav
- = link_to icon('bars'), '#', class: 'toggle-nav-collapse', title: "Open sidebar"
.sidebar-wrapper.nicescroll{ class: nav_sidebar_class }
.header-logo
%a#logo
@@ -10,19 +8,15 @@
.gitlab-text-container
%h3 GitLab
- - primary_sidebar = current_user ? 'dashboard' : 'explore'
-
- - if defined?(sidebar) && sidebar && sidebar != primary_sidebar
- .complex-sidebar
- .nav-primary
- = render "layouts/nav/#{primary_sidebar}"
- .nav-secondary
- = render "layouts/nav/#{sidebar}"
+ - if defined?(sidebar) && sidebar
+ = render "layouts/nav/#{sidebar}"
+ - elsif current_user
+ = render 'layouts/nav/dashboard'
- else
- = render "layouts/nav/#{primary_sidebar}"
+ = render 'layouts/nav/explore'
.collapse-nav
- = link_to icon('angle-left'), '#', class: 'toggle-nav-collapse', title: "Hide sidebar"
+ = render partial: 'layouts/collapse_button'
- if current_user
= link_to current_user, class: 'sidebar-user', title: "Profile" do
= image_tag avatar_icon(current_user, 60), alt: 'Profile', class: 'avatar avatar s36'
diff --git a/app/views/layouts/_search.html.haml b/app/views/layouts/_search.html.haml
index ba04bd74b8d..6b208c3d0bb 100644
--- a/app/views/layouts/_search.html.haml
+++ b/app/views/layouts/_search.html.haml
@@ -1,6 +1,6 @@
-- if controller.controller_path =~ /^groups/
+- if controller.controller_path =~ /^groups/ && @group.persisted?
- label = 'This group'
-- if controller.controller_path =~ /^projects/
+- if controller.controller_path =~ /^projects/ && @project.persisted?
- label = 'This project'
.search.search-form{class: "#{'has-location-badge' if label.present?}"}
diff --git a/app/views/layouts/nav/_admin.html.haml b/app/views/layouts/nav/_admin.html.haml
index 22d1d4d8597..280a1b93729 100644
--- a/app/views/layouts/nav/_admin.html.haml
+++ b/app/views/layouts/nav/_admin.html.haml
@@ -95,7 +95,7 @@
Spam Logs
%span.count= number_with_delimiter(SpamLog.count(:all))
- = nav_link(controller: :application_settings) do
+ = nav_link(controller: :application_settings, html_options: { class: 'separate-item'}) do
= link_to admin_application_settings_path, title: 'Settings' do
= icon('cogs fw')
%span
diff --git a/app/views/layouts/nav/_dashboard.html.haml b/app/views/layouts/nav/_dashboard.html.haml
index d1a180e4299..5cef652da14 100644
--- a/app/views/layouts/nav/_dashboard.html.haml
+++ b/app/views/layouts/nav/_dashboard.html.haml
@@ -9,18 +9,18 @@
= icon('bell fw')
%span
Todos
- %span.count= number_with_delimiter(todos_pending_count)
+ %span.count.todos-pending-count= number_with_delimiter(todos_pending_count)
= nav_link(path: 'dashboard#activity') do
= link_to activity_dashboard_path, class: 'shortcuts-activity', title: 'Activity' do
= icon('dashboard fw')
%span
Activity
- = nav_link(path: ['dashboard/groups#index', 'explore/groups#index']) do
+ = nav_link(controller: :groups) do
= link_to dashboard_groups_path, title: 'Groups' do
= icon('group fw')
%span
Groups
- = nav_link(path: 'dashboard#milestones') do
+ = nav_link(controller: :milestones) do
= link_to dashboard_milestones_path, title: 'Milestones' do
= icon('clock-o fw')
%span
@@ -48,6 +48,7 @@
%span
Help
+ %li.separate-item
= nav_link(controller: :profile) do
= link_to profile_path, title: 'Profile Settings', data: {placement: 'bottom'} do
= icon('user fw')
diff --git a/app/views/layouts/nav/_group.html.haml b/app/views/layouts/nav/_group.html.haml
index 0b7de9633ec..55940741dc0 100644
--- a/app/views/layouts/nav/_group.html.haml
+++ b/app/views/layouts/nav/_group.html.haml
@@ -1,4 +1,12 @@
%ul.nav.nav-sidebar
+ = nav_link do
+ = link_to root_path, title: 'Go to dashboard', class: 'back-link' do
+ = icon('caret-square-o-left fw')
+ %span
+ Go to dashboard
+
+ %li.separate-item
+
= nav_link(path: 'groups#show', html_options: {class: 'home'}) do
= link_to group_path(@group), title: 'Home' do
= icon('group fw')
@@ -34,7 +42,7 @@
%span
Members
- if can?(current_user, :admin_group, @group)
- = nav_link do
+ = nav_link(html_options: { class: "separate-item" }) do
= link_to edit_group_path(@group), title: 'Settings' do
= icon ('cogs fw')
%span
diff --git a/app/views/layouts/nav/_profile.html.haml b/app/views/layouts/nav/_profile.html.haml
index cc119fd64e6..3b9d31a6fc5 100644
--- a/app/views/layouts/nav/_profile.html.haml
+++ b/app/views/layouts/nav/_profile.html.haml
@@ -1,4 +1,12 @@
%ul.nav.nav-sidebar
+ = nav_link do
+ = link_to root_path, title: 'Go to dashboard', class: 'back-link' do
+ = icon('caret-square-o-left fw')
+ %span
+ Go to dashboard
+
+ %li.separate-item
+
= nav_link(path: 'profiles#show', html_options: {class: 'home'}) do
= link_to profile_path, title: 'Profile Settings' do
= icon('user fw')
diff --git a/app/views/layouts/nav/_project.html.haml b/app/views/layouts/nav/_project.html.haml
index d0f82b5f57f..86b46e8c75e 100644
--- a/app/views/layouts/nav/_project.html.haml
+++ b/app/views/layouts/nav/_project.html.haml
@@ -1,4 +1,19 @@
%ul.nav.nav-sidebar
+ - if @project.group
+ = nav_link do
+ = link_to group_path(@project.group), title: 'Go to group', class: 'back-link' do
+ = icon('caret-square-o-left fw')
+ %span
+ Go to group
+ - else
+ = nav_link do
+ = link_to root_path, title: 'Go to dashboard', class: 'back-link' do
+ = icon('caret-square-o-left fw')
+ %span
+ Go to dashboard
+
+ %li.separate-item
+
= nav_link(path: 'projects#show', html_options: {class: 'home'}) do
= link_to project_path(@project), title: 'Project', class: 'shortcuts-project' do
= icon('bookmark fw')
@@ -98,7 +113,7 @@
Snippets
- if project_nav_tab? :settings
- = nav_link(html_options: {class: "#{project_tab_class}"}) do
+ = nav_link(html_options: {class: "#{project_tab_class} separate-item"}) do
= link_to edit_project_path(@project), title: 'Settings' do
= icon('cogs fw')
%span
diff --git a/app/views/layouts/nav/_project_settings.html.haml b/app/views/layouts/nav/_project_settings.html.haml
index dc3050f02e5..d429a928464 100644
--- a/app/views/layouts/nav/_project_settings.html.haml
+++ b/app/views/layouts/nav/_project_settings.html.haml
@@ -51,8 +51,13 @@
= icon('code fw')
%span
Variables
- = nav_link path: 'triggers#index' do
+ = nav_link(controller: :triggers) do
= link_to namespace_project_triggers_path(@project.namespace, @project), title: 'Triggers' do
= icon('retweet fw')
%span
Triggers
+ = nav_link(controller: :badges) do
+ = link_to namespace_project_badges_path(@project.namespace, @project), title: 'Badges' do
+ = icon('star-half-empty fw')
+ %span
+ Badges
diff --git a/app/views/layouts/project.html.haml b/app/views/layouts/project.html.haml
index ab527e8e438..a7ef31acd3d 100644
--- a/app/views/layouts/project.html.haml
+++ b/app/views/layouts/project.html.haml
@@ -5,10 +5,14 @@
- content_for :scripts_body_top do
- project = @target_project || @project
+ - if @project_wiki
+ - markdown_preview_path = namespace_project_wikis_markdown_preview_path(project.namespace, project)
+ - else
+ - markdown_preview_path = markdown_preview_namespace_project_path(project.namespace, project)
- if current_user
:javascript
window.project_uploads_path = "#{namespace_project_uploads_path project.namespace,project}";
- window.markdown_preview_path = "#{markdown_preview_namespace_project_path(project.namespace, project)}";
+ window.markdown_preview_path = "#{markdown_preview_path}";
- content_for :scripts_body do
= render "layouts/init_auto_complete" if current_user
diff --git a/app/views/profiles/keys/_form.html.haml b/app/views/profiles/keys/_form.html.haml
index 4d78215ed3c..b3ed59a1a4a 100644
--- a/app/views/profiles/keys/_form.html.haml
+++ b/app/views/profiles/keys/_form.html.haml
@@ -1,10 +1,6 @@
%div
= form_for [:profile, @key], html: { class: 'js-requires-input' } do |f|
- - if @key.errors.any?
- .alert.alert-danger
- %ul
- - @key.errors.full_messages.each do |msg|
- %li= msg
+ = form_errors(@key)
.form-group
= f.label :key, class: 'label-light'
diff --git a/app/views/profiles/notifications/show.html.haml b/app/views/profiles/notifications/show.html.haml
index 3d15c0d932b..6609295a2a5 100644
--- a/app/views/profiles/notifications/show.html.haml
+++ b/app/views/profiles/notifications/show.html.haml
@@ -2,11 +2,7 @@
- header_title page_title, profile_notifications_path
= form_for @user, url: profile_notifications_path, method: :put, html: { class: 'update-notifications prepend-top-default' } do |f|
- -if @user.errors.any?
- %div.alert.alert-danger
- %ul
- - @user.errors.full_messages.each do |msg|
- %li= msg
+ = form_errors(@user)
= hidden_field_tag :notification_type, 'global'
.row
diff --git a/app/views/profiles/passwords/edit.html.haml b/app/views/profiles/passwords/edit.html.haml
index 44d758dceb3..5ac8a8b9d09 100644
--- a/app/views/profiles/passwords/edit.html.haml
+++ b/app/views/profiles/passwords/edit.html.haml
@@ -13,11 +13,8 @@
- unless @user.password_automatically_set?
or recover your current one
= form_for @user, url: profile_password_path, method: :put, html: {class: "update-password"} do |f|
- -if @user.errors.any?
- .alert.alert-danger
- %ul
- - @user.errors.full_messages.each do |msg|
- %li= msg
+ = form_errors(@user)
+
- unless @user.password_automatically_set?
.form-group
= f.label :current_password, class: 'label-light'
diff --git a/app/views/profiles/passwords/new.html.haml b/app/views/profiles/passwords/new.html.haml
index d165f758c81..2eb9fac57c3 100644
--- a/app/views/profiles/passwords/new.html.haml
+++ b/app/views/profiles/passwords/new.html.haml
@@ -7,11 +7,8 @@
Please set a new password before proceeding.
%br
After a successful password update you will be redirected to login screen.
- -if @user.errors.any?
- .alert.alert-danger
- %ul
- - @user.errors.full_messages.each do |msg|
- %li= msg
+
+ = form_errors(@user)
- unless @user.password_automatically_set?
.form-group
diff --git a/app/views/profiles/show.html.haml b/app/views/profiles/show.html.haml
index dcb3be9585d..f59d27f7ed0 100644
--- a/app/views/profiles/show.html.haml
+++ b/app/views/profiles/show.html.haml
@@ -1,9 +1,6 @@
= form_for @user, url: profile_path, method: :put, html: { multipart: true, class: "edit-user prepend-top-default" }, authenticity_token: true do |f|
- -if @user.errors.any?
- %div.alert.alert-danger
- %ul
- - @user.errors.full_messages.each do |msg|
- %li= msg
+ = form_errors(@user)
+
.row
.col-lg-3.profile-settings-sidebar
%h4.prepend-top-0
diff --git a/app/views/projects/_errors.html.haml b/app/views/projects/_errors.html.haml
index 7c8bb33ed7e..2dba22d3be6 100644
--- a/app/views/projects/_errors.html.haml
+++ b/app/views/projects/_errors.html.haml
@@ -1,4 +1 @@
-- if @project.errors.any?
- .alert.alert-danger
- %button{ type: "button", class: "close", "data-dismiss" => "alert"} &times;
- = @project.errors.full_messages.first
+= form_errors(@project)
diff --git a/app/views/projects/_md_preview.html.haml b/app/views/projects/_md_preview.html.haml
index 4920910fee1..7a78d61a611 100644
--- a/app/views/projects/_md_preview.html.haml
+++ b/app/views/projects/_md_preview.html.haml
@@ -2,13 +2,13 @@
.md-header
%ul.nav-links
%li.active
- %a.js-md-write-button{ href: "#md-write-holder" }
+ %a.js-md-write-button{ href: "#md-write-holder", tabindex: -1 }
Write
%li
- %a.js-md-preview-button{ href: "#md-preview-holder" }
+ %a.js-md-preview-button{ href: "#md-preview-holder", tabindex: -1 }
Preview
%li.pull-right
- %button.zen-cotrol.zen-control-full.js-zen-enter{ type: 'button' }
+ %button.zen-cotrol.zen-control-full.js-zen-enter{ type: 'button', tabindex: -1 }
Go full screen
.md-write-holder
diff --git a/app/views/projects/badges/index.html.haml b/app/views/projects/badges/index.html.haml
new file mode 100644
index 00000000000..c22384ddf46
--- /dev/null
+++ b/app/views/projects/badges/index.html.haml
@@ -0,0 +1,24 @@
+- page_title 'Badges'
+- badges_path = namespace_project_badges_path(@project.namespace, @project)
+- header_title project_title(@project, 'Badges', badges_path)
+
+.prepend-top-10
+ .panel.panel-default
+ .panel-heading
+ %b Builds badge &middot;
+ = @build_badge.to_html
+ .pull-right
+ = render 'shared/ref_switcher', destination: 'badges'
+ .panel-body
+ .row
+ .col-md-2.text-center
+ Markdown
+ .col-md-10.code.js-syntax-highlight
+ = highlight('.md', @build_badge.to_markdown)
+ .row
+ %hr
+ .row
+ .col-md-2.text-center
+ HTML
+ .col-md-10.code.js-syntax-highlight
+ = highlight('.html', @build_badge.to_html)
diff --git a/app/views/projects/commits/_commit.html.haml b/app/views/projects/commits/_commit.html.haml
index 7f2903589a9..7da89231243 100644
--- a/app/views/projects/commits/_commit.html.haml
+++ b/app/views/projects/commits/_commit.html.haml
@@ -19,24 +19,17 @@
.pull-right
- if ci_commit
= render_ci_status(ci_commit)
- &nbsp;
= clipboard_button(clipboard_text: commit.id)
= link_to commit.short_id, namespace_project_commit_path(project.namespace, project, commit), class: "commit_short_id"
- .notes_count
- - if note_count > 0
- %span.light
- %i.fa.fa-comments
- = note_count
-
- if commit.description?
.commit-row-description.js-toggle-content
%pre
= preserve(markdown(escape_once(commit.description), pipeline: :single_line))
.commit-row-info
+ by
= commit_author_link(commit, avatar: true, size: 24)
- authored
.committed_ago
#{time_ago_with_tooltip(commit.committed_date, skip_js: true)} &nbsp;
= link_to_browse_code(project, commit)
diff --git a/app/views/projects/deploy_keys/_form.html.haml b/app/views/projects/deploy_keys/_form.html.haml
index 5e182af2669..f6565f85836 100644
--- a/app/views/projects/deploy_keys/_form.html.haml
+++ b/app/views/projects/deploy_keys/_form.html.haml
@@ -1,10 +1,6 @@
%div
= form_for [@project.namespace.becomes(Namespace), @project, @key], url: namespace_project_deploy_keys_path, html: { class: 'deploy-key-form form-horizontal js-requires-input' } do |f|
- -if @key.errors.any?
- .alert.alert-danger
- %ul
- - @key.errors.full_messages.each do |msg|
- %li= msg
+ = form_errors(@key)
.form-group
= f.label :title, class: "control-label"
diff --git a/app/views/projects/diffs/_diffs.html.haml b/app/views/projects/diffs/_diffs.html.haml
index 2e1a37aa06d..eaab99973a4 100644
--- a/app/views/projects/diffs/_diffs.html.haml
+++ b/app/views/projects/diffs/_diffs.html.haml
@@ -3,7 +3,7 @@
- diff_files = safe_diff_files(diffs, diff_refs)
-.content-block.oneline-block
+.content-block.oneline-block.files-changed
.inline-parallel-buttons
.btn-group
= inline_diff_btn
diff --git a/app/views/projects/diffs/_file.html.haml b/app/views/projects/diffs/_file.html.haml
index 698ed02ea0e..83a8d7ae9bf 100644
--- a/app/views/projects/diffs/_file.html.haml
+++ b/app/views/projects/diffs/_file.html.haml
@@ -3,7 +3,7 @@
- if diff_file.diff.submodule?
%span
= icon('archive fw')
- %strong
+ %span
= submodule_link(blob, @commit.id, project.repository)
- else
= blob_icon blob.mode, blob.name
@@ -11,13 +11,13 @@
= link_to "#diff-#{i}" do
- if diff_file.renamed_file
- old_path, new_path = mark_inline_diffs(diff_file.old_path, diff_file.new_path)
- %strong.filename.old
+ .filename.old
= old_path
&rarr;
- %strong.filename.new
+ .filename.new
= new_path
- else
- %strong
+ %span
= diff_file.new_path
- if diff_file.deleted_file
deleted
@@ -28,8 +28,8 @@
.file-actions.hidden-xs
- if blob_text_viewable?(blob)
- = link_to '#', class: 'js-toggle-diff-comments btn active has-tooltip', title: "Toggle comments for this file" do
- = icon('comments')
+ = link_to '#', class: 'js-toggle-diff-comments btn active has-tooltip btn-file-option', title: "Toggle comments for this file" do
+ = icon('comment')
\
- if editable_diff?(diff_file)
diff --git a/app/views/projects/hooks/index.html.haml b/app/views/projects/hooks/index.html.haml
index 67d016bd871..e39224d86c6 100644
--- a/app/views/projects/hooks/index.html.haml
+++ b/app/views/projects/hooks/index.html.haml
@@ -9,10 +9,8 @@
%hr.clearfix
= form_for [@project.namespace.becomes(Namespace), @project, @hook], as: :hook, url: namespace_project_hooks_path(@project.namespace, @project), html: { class: 'form-horizontal' } do |f|
- -if @hook.errors.any?
- .alert.alert-danger
- - @hook.errors.full_messages.each do |msg|
- %p= msg
+ = form_errors(@hook)
+
.form-group
= f.label :url, "URL", class: 'control-label'
.col-sm-10
diff --git a/app/views/projects/labels/_form.html.haml b/app/views/projects/labels/_form.html.haml
index be7a0bb5628..aa143e54ffe 100644
--- a/app/views/projects/labels/_form.html.haml
+++ b/app/views/projects/labels/_form.html.haml
@@ -1,11 +1,5 @@
= form_for [@project.namespace.becomes(Namespace), @project, @label], html: { class: 'form-horizontal label-form js-quick-submit js-requires-input' } do |f|
- -if @label.errors.any?
- .row
- .col-sm-offset-2.col-sm-10
- .alert.alert-danger
- - @label.errors.full_messages.each do |msg|
- %span= msg
- %br
+ = form_errors(@label)
.form-group
= f.label :title, class: 'control-label'
diff --git a/app/views/projects/labels/_label.html.haml b/app/views/projects/labels/_label.html.haml
index 0612863296a..097a65969a6 100644
--- a/app/views/projects/labels/_label.html.haml
+++ b/app/views/projects/labels/_label.html.haml
@@ -1,24 +1,27 @@
%li{id: dom_id(label)}
= render "shared/label_row", label: label
- .pull-right
- %strong.append-right-20
+ .pull-info-right
+ %span.append-right-20
= link_to_label(label, type: :merge_request) do
- = pluralize label.open_merge_requests_count, 'open merge request'
+ = pluralize label.open_merge_requests_count, 'merge request'
- %strong.append-right-20
+ %span.append-right-20
= link_to_label(label) do
= pluralize label.open_issues_count(current_user), 'open issue'
- if current_user
.label-subscription{data: {url: toggle_subscription_namespace_project_label_path(@project.namespace, @project, label)}}
.subscription-status{data: {status: label_subscription_status(label)}}
- %button.btn.btn-sm.btn-info.subscribe-button
+
+ %a.subscribe-button.btn.action-buttons{data: {toggle: "tooltip"}}
%span= label_subscription_toggle_button_text(label)
- if can? current_user, :admin_label, @project
- = link_to 'Edit', edit_namespace_project_label_path(@project.namespace, @project, label), class: 'btn btn-sm'
- = link_to 'Delete', namespace_project_label_path(@project.namespace, @project, label), class: 'btn btn-sm btn-remove remove-row', method: :delete, remote: true, data: {confirm: "Remove this label? Are you sure?"}
+ = link_to edit_namespace_project_label_path(@project.namespace, @project, label), title: "Edit", class: 'btn action-buttons', data: {toggle: "tooltip"} do
+ %i.fa.fa-pencil-square-o
+ = link_to namespace_project_label_path(@project.namespace, @project, label), title: "Delete", class: 'btn action-buttons remove-row', method: :delete, remote: true, data: {confirm: "Remove this label? Are you sure?", toggle: "tooltip"} do
+ %i.fa.fa-trash-o
- if current_user
:javascript
diff --git a/app/views/projects/merge_requests/_new_compare.html.haml b/app/views/projects/merge_requests/_new_compare.html.haml
index 01dc7519bee..7d7c487e970 100644
--- a/app/views/projects/merge_requests/_new_compare.html.haml
+++ b/app/views/projects/merge_requests/_new_compare.html.haml
@@ -5,33 +5,74 @@
.hide.alert.alert-danger.mr-compare-errors
.merge-request-branches.row
.col-md-6
- .panel.panel-default
+ .panel.panel-default.panel-new-merge-request
.panel-heading
- %strong Source branch
- .panel-body
- = f.select(:source_project_id, [[@merge_request.source_project_path,@merge_request.source_project.id]] , {}, { class: 'source_project select2 span3', disabled: @merge_request.persisted?, required: true })
- &nbsp;
- = f.select(:source_branch, @merge_request.source_branches, { include_blank: true }, { class: 'source_branch select2 span2', required: true, data: { placeholder: "Select source branch" } })
+ Source branch
+ .panel-body.clearfix
+ .merge-request-select.dropdown
+ = f.hidden_field :source_project_id
+ = dropdown_toggle @merge_request.source_project_path, { toggle: "dropdown", field_name: "#{f.object_name}[source_project_id]", disabled: @merge_request.persisted? }, { toggle_class: "js-compare-dropdown js-source-project" }
+ .dropdown-menu.dropdown-menu-selectable.dropdown-source-project
+ = dropdown_title("Select source project")
+ = dropdown_filter("Search projects")
+ = dropdown_content do
+ - is_active = f.object.source_project_id == @merge_request.source_project.id
+ %ul
+ %li
+ %a{ href: "#", class: "#{("is-active" if is_active)}", data: { id: @merge_request.source_project.id } }
+ = @merge_request.source_project_path
+ .merge-request-select.dropdown
+ = f.hidden_field :source_branch
+ = dropdown_toggle "Select source branch", { toggle: "dropdown", field_name: "#{f.object_name}[source_branch]" }, { toggle_class: "js-compare-dropdown js-source-branch" }
+ .dropdown-menu.dropdown-menu-selectable.dropdown-source-branch
+ = dropdown_title("Select source branch")
+ = dropdown_filter("Search branches")
+ = dropdown_content do
+ %ul
+ - @merge_request.source_branches.each do |branch|
+ %li
+ %a{ href: "#", class: "#{("is-active" if f.object.source_branch == branch)}", data: { id: branch } }
+ = branch
.panel-footer
- .mr_source_commit
+ = icon('spinner spin', class: 'js-source-loading')
+ %ul.list-unstyled.mr_source_commit
.col-md-6
- .panel.panel-default
+ .panel.panel-default.panel-new-merge-request
.panel-heading
- %strong Target branch
- .panel-body
+ Target branch
+ .panel-body.clearfix
- projects = @project.forked_from_project.nil? ? [@project] : [@project, @project.forked_from_project]
- = f.select(:target_project_id, options_from_collection_for_select(projects, 'id', 'path_with_namespace', f.object.target_project_id), {}, { class: 'target_project select2 span3', disabled: @merge_request.persisted?, required: true })
- &nbsp;
- = f.select(:target_branch, @merge_request.target_branches, { include_blank: true }, { class: 'target_branch select2 span2', required: true, data: { placeholder: "Select target branch" } })
+ .merge-request-select.dropdown
+ = f.hidden_field :target_project_id
+ = dropdown_toggle f.object.target_project.path_with_namespace, { toggle: "dropdown", field_name: "#{f.object_name}[target_project_id]", disabled: @merge_request.persisted? }, { toggle_class: "js-compare-dropdown js-target-project" }
+ .dropdown-menu.dropdown-menu-selectable.dropdown-target-project
+ = dropdown_title("Select target project")
+ = dropdown_filter("Search projects")
+ = dropdown_content do
+ %ul
+ - projects.each do |project|
+ %li
+ %a{ href: "#", class: "#{("is-active" if f.object.target_project_id == project.id)}", data: { id: project.id } }
+ = project.path_with_namespace
+ .merge-request-select.dropdown
+ = f.hidden_field :target_branch
+ = dropdown_toggle f.object.target_branch, { toggle: "dropdown", field_name: "#{f.object_name}[target_branch]" }, { toggle_class: "js-compare-dropdown js-target-branch" }
+ .dropdown-menu.dropdown-menu-selectable.dropdown-target-branch.js-target-branch-dropdown
+ = dropdown_title("Select target branch")
+ = dropdown_filter("Search branches")
+ = dropdown_content do
+ %ul
+ - @merge_request.target_branches.each do |branch|
+ %li
+ %a{ href: "#", class: "#{("is-active" if f.object.target_branch == branch)}", data: { id: branch } }
+ = branch
.panel-footer
- .mr_target_commit
+ = icon('spinner spin', class: "js-target-loading")
+ %ul.list-unstyled.mr_target_commit
- if @merge_request.errors.any?
- .alert.alert-danger
- - @merge_request.errors.full_messages.each do |msg|
- %div= msg
-
+ = form_errors(@merge_request)
- elsif @merge_request.source_branch.present? && @merge_request.target_branch.present?
.light-well.append-bottom-default
.center
@@ -45,40 +86,11 @@
and
%span.label-branch #{@merge_request.target_branch}
are the same.
-
-
- .form-actions
- = f.submit 'Compare branches and continue', class: "btn btn-new mr-compare-btn"
-
-:javascript
- var source_branch = $("#merge_request_source_branch")
- , target_branch = $("#merge_request_target_branch")
- , target_project = $("#merge_request_target_project_id");
-
- $.get("#{branch_from_namespace_project_merge_requests_path(@source_project.namespace, @source_project)}", {ref: source_branch.val() });
- $.get("#{branch_to_namespace_project_merge_requests_path(@source_project.namespace, @source_project)}", {target_project_id: target_project.val(),ref: target_branch.val() });
-
- target_project.on("change", function() {
- $.get("#{update_branches_namespace_project_merge_requests_path(@source_project.namespace, @source_project)}", {target_project_id: $(this).val() });
- });
- source_branch.on("change", function() {
- $.get("#{branch_from_namespace_project_merge_requests_path(@source_project.namespace, @source_project)}", {ref: $(this).val() });
- $(".mr-compare-errors").fadeOut();
- $(".mr-compare-btn").enable();
- });
- target_branch.on("change", function() {
- $.get("#{branch_to_namespace_project_merge_requests_path(@source_project.namespace, @source_project)}", {target_project_id: target_project.val(),ref: $(this).val() });
- $(".mr-compare-errors").fadeOut();
- $(".mr-compare-btn").enable();
- });
-
+ = f.submit 'Compare branches and continue', class: "btn btn-new mr-compare-btn"
:javascript
- $(".merge-request-form").on('submit', function () {
- if ($("#merge_request_source_branch").val() === "" || $('#merge_request_target_branch').val() === "") {
- $(".mr-compare-errors").html("You must select source and target branch to proceed");
- $(".mr-compare-errors").fadeIn();
- event.preventDefault();
- return;
- }
+ new Compare({
+ targetProjectUrl: "#{update_branches_namespace_project_merge_requests_path(@source_project.namespace, @source_project)}",
+ sourceBranchUrl: "#{branch_from_namespace_project_merge_requests_path(@source_project.namespace, @source_project)}",
+ targetBranchUrl: "#{branch_to_namespace_project_merge_requests_path(@source_project.namespace, @source_project)}"
});
diff --git a/app/views/projects/merge_requests/branch_from.html.haml b/app/views/projects/merge_requests/branch_from.html.haml
new file mode 100644
index 00000000000..4f90dde6fa8
--- /dev/null
+++ b/app/views/projects/merge_requests/branch_from.html.haml
@@ -0,0 +1 @@
+= commit_to_html(@commit, @source_project, false)
diff --git a/app/views/projects/merge_requests/branch_from.js.haml b/app/views/projects/merge_requests/branch_from.js.haml
deleted file mode 100644
index 9210798f39c..00000000000
--- a/app/views/projects/merge_requests/branch_from.js.haml
+++ /dev/null
@@ -1,3 +0,0 @@
-:plain
- $(".mr_source_commit").html("#{commit_to_html(@commit, @source_project, false)}");
- $('.js-timeago').timeago()
diff --git a/app/views/projects/merge_requests/branch_to.html.haml b/app/views/projects/merge_requests/branch_to.html.haml
new file mode 100644
index 00000000000..67a7a6bcec9
--- /dev/null
+++ b/app/views/projects/merge_requests/branch_to.html.haml
@@ -0,0 +1 @@
+= commit_to_html(@commit, @target_project, false)
diff --git a/app/views/projects/merge_requests/branch_to.js.haml b/app/views/projects/merge_requests/branch_to.js.haml
deleted file mode 100644
index 32fe2d535f3..00000000000
--- a/app/views/projects/merge_requests/branch_to.js.haml
+++ /dev/null
@@ -1,3 +0,0 @@
-:plain
- $(".mr_target_commit").html("#{commit_to_html(@commit, @target_project, false)}");
- $('.js-timeago').timeago()
diff --git a/app/views/projects/merge_requests/update_branches.html.haml b/app/views/projects/merge_requests/update_branches.html.haml
new file mode 100644
index 00000000000..1b93188a10c
--- /dev/null
+++ b/app/views/projects/merge_requests/update_branches.html.haml
@@ -0,0 +1,5 @@
+%ul
+ - @target_branches.each do |branch|
+ %li
+ %a{ href: "#", class: "#{("is-active" if "a" == branch)}", data: { id: branch } }
+ = branch
diff --git a/app/views/projects/merge_requests/update_branches.js.haml b/app/views/projects/merge_requests/update_branches.js.haml
deleted file mode 100644
index ca21b3bc0de..00000000000
--- a/app/views/projects/merge_requests/update_branches.js.haml
+++ /dev/null
@@ -1,9 +0,0 @@
-:plain
- $(".target_branch").html("#{escape_javascript(options_for_select(@target_branches))}");
-
- $('select.target_branch').select2({
- width: 'resolve',
- dropdownAutoWidth: true
- });
-
- $(".mr_target_commit").html("");
diff --git a/app/views/projects/merge_requests/widget/_show.html.haml b/app/views/projects/merge_requests/widget/_show.html.haml
index 2be06aebe6c..92d95358937 100644
--- a/app/views/projects/merge_requests/widget/_show.html.haml
+++ b/app/views/projects/merge_requests/widget/_show.html.haml
@@ -22,4 +22,6 @@
if(typeof merge_request_widget === 'undefined') {
merge_request_widget = new MergeRequestWidget(opts);
+ } else {
+ merge_request_widget.setOpts(opts);
}
diff --git a/app/views/projects/milestones/_form.html.haml b/app/views/projects/milestones/_form.html.haml
index 23f2bca7baf..b2dae1c70ee 100644
--- a/app/views/projects/milestones/_form.html.haml
+++ b/app/views/projects/milestones/_form.html.haml
@@ -1,9 +1,6 @@
= form_for [@project.namespace.becomes(Namespace), @project, @milestone], html: {class: 'form-horizontal milestone-form gfm-form js-quick-submit js-requires-input'} do |f|
- -if @milestone.errors.any?
- .alert.alert-danger
- %ul
- - @milestone.errors.full_messages.each do |msg|
- %li= msg
+ = form_errors(@milestone)
+
.row
.col-md-6
.form-group
diff --git a/app/views/projects/notes/_diff_notes_with_reply.html.haml b/app/views/projects/notes/_diff_notes_with_reply.html.haml
index 11f9859a90f..39be072855a 100644
--- a/app/views/projects/notes/_diff_notes_with_reply.html.haml
+++ b/app/views/projects/notes/_diff_notes_with_reply.html.haml
@@ -3,9 +3,6 @@
- if !defined?(line) || line == note.diff_line
%tr.notes_holder
%td.notes_line{ colspan: 2 }
- %span.discussion-notes-count
- %i.fa.fa-comment
- = notes.count
%td.notes_content
%ul.notes{ data: { discussion_id: note.discussion_id } }
= render notes
diff --git a/app/views/projects/notes/_diff_notes_with_reply_parallel.html.haml b/app/views/projects/notes/_diff_notes_with_reply_parallel.html.haml
index bb761ed2f94..f8aa5e2fa7d 100644
--- a/app/views/projects/notes/_diff_notes_with_reply_parallel.html.haml
+++ b/app/views/projects/notes/_diff_notes_with_reply_parallel.html.haml
@@ -4,9 +4,6 @@
%tr.notes_holder
- if note1
%td.notes_line.old
- %span.btn.disabled
- %i.fa.fa-comment
- = notes_left.count
%td.notes_content.parallel.old
%ul.notes{ data: { discussion_id: note1.discussion_id } }
= render notes_left
@@ -19,9 +16,6 @@
- if note2
%td.notes_line.new
- %span.btn.disabled
- %i.fa.fa-comment
- = notes_right.count
%td.notes_content.parallel.new
%ul.notes{ data: { discussion_id: note2.discussion_id } }
= render notes_right
diff --git a/app/views/projects/notes/_note.html.haml b/app/views/projects/notes/_note.html.haml
index a681d6dece4..5c42423541e 100644
--- a/app/views/projects/notes/_note.html.haml
+++ b/app/views/projects/notes/_note.html.haml
@@ -17,8 +17,8 @@
%span.note-role
= access
= link_to '#', title: 'Edit comment', class: 'note-action-button js-note-edit' do
- = icon('pencil-square-o')
- = link_to namespace_project_note_path(note.project.namespace, note.project, note), title: 'Remove comment', method: :delete, data: { confirm: 'Are you sure you want to remove this comment?' }, remote: true, class: 'note-action-button js-note-delete' do
+ = icon('pencil')
+ = link_to namespace_project_note_path(note.project.namespace, note.project, note), title: 'Remove comment', method: :delete, data: { confirm: 'Are you sure you want to remove this comment?' }, remote: true, class: 'note-action-button js-note-delete danger' do
= icon('trash-o')
.note-body{class: note_editable?(note) ? 'js-task-list-container' : ''}
.note-text
diff --git a/app/views/projects/protected_branches/index.html.haml b/app/views/projects/protected_branches/index.html.haml
index cfd7e1534ca..653b02da4db 100644
--- a/app/views/projects/protected_branches/index.html.haml
+++ b/app/views/projects/protected_branches/index.html.haml
@@ -13,11 +13,7 @@
- if can? current_user, :admin_project, @project
= form_for [@project.namespace.becomes(Namespace), @project, @protected_branch], html: { class: 'form-horizontal' } do |f|
- -if @protected_branch.errors.any?
- .alert.alert-danger
- %ul
- - @protected_branch.errors.full_messages.each do |msg|
- %li= msg
+ = form_errors(@protected_branch)
.form-group
= f.label :name, "Branch", class: 'control-label'
diff --git a/app/views/projects/variables/show.html.haml b/app/views/projects/variables/show.html.haml
index efe1e6f24c2..ca284b84d39 100644
--- a/app/views/projects/variables/show.html.haml
+++ b/app/views/projects/variables/show.html.haml
@@ -13,13 +13,7 @@
= nested_form_for @project, url: url_for(controller: 'projects/variables', action: 'update'), html: { class: 'form-horizontal' } do |f|
- - if @project.errors.any?
- #error_explanation
- %p.lead= "#{pluralize(@project.errors.count, "error")} prohibited this project from being saved:"
- .alert.alert-error
- %ul
- - @project.errors.full_messages.each do |msg|
- %li= msg
+ = form_errors(@project)
= f.fields_for :variables do |variable_form|
.form-group
diff --git a/app/views/projects/wikis/_form.html.haml b/app/views/projects/wikis/_form.html.haml
index f0d1932e23c..812876e2835 100644
--- a/app/views/projects/wikis/_form.html.haml
+++ b/app/views/projects/wikis/_form.html.haml
@@ -1,9 +1,5 @@
= form_for [@project.namespace.becomes(Namespace), @project, @page], method: @page.persisted? ? :put : :post, html: { class: 'form-horizontal wiki-form gfm-form prepend-top-default js-quick-submit' } do |f|
- -if @page.errors.any?
- #error_explanation
- .alert.alert-danger
- - @page.errors.full_messages.each do |msg|
- %p= msg
+ = form_errors(@page)
= f.hidden_field :title, value: @page.title
.form-group
diff --git a/app/views/shared/_label_row.html.haml b/app/views/shared/_label_row.html.haml
index 4b47b0291be..b38c5e18efb 100644
--- a/app/views/shared/_label_row.html.haml
+++ b/app/views/shared/_label_row.html.haml
@@ -1,4 +1,5 @@
%span.label-row
- = link_to_label(label, tooltip: false)
+ %span.label-name
+ = link_to_label(label, tooltip: false)
%span.prepend-left-10
= markdown(label.description, pipeline: :single_line)
diff --git a/app/views/shared/_service_settings.html.haml b/app/views/shared/_service_settings.html.haml
index 5a60ff5a5da..fc935166bf6 100644
--- a/app/views/shared/_service_settings.html.haml
+++ b/app/views/shared/_service_settings.html.haml
@@ -1,9 +1,4 @@
-- if @service.errors.any?
- #error_explanation
- .alert.alert-danger
- %ul
- - @service.errors.full_messages.each do |msg|
- %li= msg
+= form_errors(@service)
- if @service.help.present?
.well
diff --git a/app/views/shared/issuable/_form.html.haml b/app/views/shared/issuable/_form.html.haml
index e2a9e5bfb92..757a3812deb 100644
--- a/app/views/shared/issuable/_form.html.haml
+++ b/app/views/shared/issuable/_form.html.haml
@@ -1,10 +1,5 @@
-- if issuable.errors.any?
- .row
- .col-sm-offset-2.col-sm-10
- .alert.alert-danger
- - issuable.errors.full_messages.each do |msg|
- %span= msg
- %br
+= form_errors(issuable)
+
.form-group
= f.label :title, class: 'control-label'
.col-sm-10
@@ -53,10 +48,11 @@
.issue-assignee
= f.label :assignee_id, "Assignee", class: 'control-label'
.col-sm-10
- = users_select_tag("#{issuable.class.model_name.param_key}[assignee_id]",
- placeholder: 'Select assignee', class: 'custom-form-control', null_user: true,
- selected: issuable.assignee_id, project: @target_project || @project,
- first_user: true, current_user: true, include_blank: true)
+ .issuable-form-select-holder
+ = users_select_tag("#{issuable.class.model_name.param_key}[assignee_id]",
+ placeholder: 'Select assignee', class: 'custom-form-control', null_user: true,
+ selected: issuable.assignee_id, project: @target_project || @project,
+ first_user: true, current_user: true, include_blank: true)
&nbsp;
= link_to 'Assign to me', '#', class: 'btn assign-to-me-link'
.form-group
@@ -64,8 +60,9 @@
= f.label :milestone_id, "Milestone", class: 'control-label'
.col-sm-10
- if milestone_options(issuable).present?
- = f.select(:milestone_id, milestone_options(issuable),
- { include_blank: true }, { class: 'select2', data: { placeholder: 'Select milestone' } })
+ .issuable-form-select-holder
+ = f.select(:milestone_id, milestone_options(issuable),
+ { include_blank: true }, { class: 'select2', data: { placeholder: 'Select milestone' } })
- else
.prepend-top-10
%span.light No open milestones available.
diff --git a/app/views/shared/issuable/_sidebar.html.haml b/app/views/shared/issuable/_sidebar.html.haml
index 47e544acf52..94affa4b59a 100644
--- a/app/views/shared/issuable/_sidebar.html.haml
+++ b/app/views/shared/issuable/_sidebar.html.haml
@@ -1,5 +1,6 @@
%aside.right-sidebar{ class: sidebar_gutter_collapsed_class }
.issuable-sidebar
+ - can_edit_issuable = can?(current_user, :"admin_#{issuable.to_ability_name}", @project)
.block.issuable-sidebar-header
%span.issuable-count.hide-collapsed.pull-left
= issuable.iid
@@ -29,7 +30,7 @@
.title.hide-collapsed
Assignee
= icon('spinner spin', class: 'block-loading')
- - if can?(current_user, :"admin_#{issuable.to_ability_name}", @project)
+ - if can_edit_issuable
= link_to 'Edit', '#', class: 'edit-link pull-right'
.value.bold.hide-collapsed
- if issuable.assignee
@@ -41,9 +42,10 @@
= issuable.assignee.to_reference
- else
%span.assign-yourself
- No assignee -
- %a.js-assign-yourself{ href: '#' }
- assign yourself
+ No assignee
+ - if can_edit_issuable
+ %a.js-assign-yourself{ href: '#' }
+ \- assign yourself
.selectbox.hide-collapsed
= f.hidden_field 'assignee_id', value: issuable.assignee_id, id: 'issue_assignee_id'
@@ -60,7 +62,7 @@
.title.hide-collapsed
Milestone
= icon('spinner spin', class: 'block-loading')
- - if can?(current_user, :"admin_#{issuable.to_ability_name}", @project)
+ - if can_edit_issuable
= link_to 'Edit', '#', class: 'edit-link pull-right'
.value.bold.hide-collapsed
- if issuable.milestone
@@ -82,7 +84,7 @@
.title.hide-collapsed
Labels
= icon('spinner spin', class: 'block-loading')
- - if can?(current_user, :"admin_#{issuable.to_ability_name}", @project)
+ - if can_edit_issuable
= link_to 'Edit', '#', class: 'edit-link pull-right'
.value.bold.issuable-show-labels.hide-collapsed{ class: ("has-labels" if issuable.labels.any?) }
- if issuable.labels.any?
diff --git a/app/views/shared/snippets/_form.html.haml b/app/views/shared/snippets/_form.html.haml
index 1041eccd1df..47ec09f62c6 100644
--- a/app/views/shared/snippets/_form.html.haml
+++ b/app/views/shared/snippets/_form.html.haml
@@ -1,10 +1,6 @@
.snippet-form-holder
= form_for @snippet, url: url, html: { class: "form-horizontal snippet-form js-requires-input" } do |f|
- - if @snippet.errors.any?
- .alert.alert-danger
- %ul
- - @snippet.errors.full_messages.each do |msg|
- %li= msg
+ = form_errors(@snippet)
.form-group
= f.label :title, class: 'control-label'
diff --git a/app/views/users/calendar.html.haml b/app/views/users/calendar.html.haml
index 7f29918dba3..1de71f37d1a 100644
--- a/app/views/users/calendar.html.haml
+++ b/app/views/users/calendar.html.haml
@@ -7,4 +7,4 @@
'#{user_calendar_activities_path}'
);
-.calendar-hint Summary of issues, merge requests and push events
+.calendar-hint Summary of issues, merge requests, and push events
diff --git a/app/views/votes/_votes_block.html.haml b/app/views/votes/_votes_block.html.haml
index 8ffcdc4a327..dc249155b92 100644
--- a/app/views/votes/_votes_block.html.haml
+++ b/app/views/votes/_votes_block.html.haml
@@ -1,7 +1,7 @@
.awards.votes-block
- awards_sort(votable.notes.awards.grouped_awards).each do |emoji, notes|
- %button.btn.award-control.js-emoji-btn.has-tooltip{class: (note_active_class(notes, current_user)), title: emoji_author_list(notes, current_user), data: {placement: "top"}}
- = emoji_icon(emoji)
+ %button.btn.award-control.js-emoji-btn.has-tooltip{class: (note_active_class(notes, current_user)), data: {placement: "top", original_title: emoji_author_list(notes, current_user)}}
+ = emoji_icon(emoji, sprite: false)
%span.award-control-text.js-counter
= notes.count