summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorAlfredo Sumaran <alfredo@gitlab.com>2016-04-06 16:35:04 -0500
committerAlfredo Sumaran <alfredo@gitlab.com>2016-04-06 16:35:04 -0500
commitbfcee4a51d8cd7cecd7a63e52f13979a436a458e (patch)
tree9905169af129a07a924286e2a7d389a00e912adb /app
parent946b4519c99a91c18a23041c090568231410785a (diff)
parentb6d5fcd4775718676f1a11ddb6a88a08c67c9d0a (diff)
downloadgitlab-ce-bfcee4a51d8cd7cecd7a63e52f13979a436a458e.tar.gz
Merge branch 'master' into issue_14952
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/gl_dropdown.js.coffee11
-rw-r--r--app/assets/javascripts/issues.js.coffee15
-rw-r--r--app/assets/javascripts/lib/url_utility.js.coffee31
-rw-r--r--app/assets/javascripts/search_autocomplete.js.coffee58
-rw-r--r--app/assets/stylesheets/framework/variables.scss20
-rw-r--r--app/assets/stylesheets/pages/projects.scss4
-rw-r--r--app/assets/stylesheets/pages/search.scss20
-rw-r--r--app/assets/stylesheets/pages/status.scss2
-rw-r--r--app/models/project_services/builds_email_service.rb11
-rw-r--r--app/views/layouts/_search.html.haml4
-rw-r--r--app/views/projects/notes/_note.html.haml2
11 files changed, 128 insertions, 50 deletions
diff --git a/app/assets/javascripts/gl_dropdown.js.coffee b/app/assets/javascripts/gl_dropdown.js.coffee
index 2a4811b8763..e8d25591f63 100644
--- a/app/assets/javascripts/gl_dropdown.js.coffee
+++ b/app/assets/javascripts/gl_dropdown.js.coffee
@@ -177,10 +177,11 @@ class GitLabDropdown
selector = ".dropdown-page-one .dropdown-content a"
@dropdown.on "click", selector, (e) ->
- selected = self.rowClicked $(@)
+ $el = $(@)
+ selected = self.rowClicked $el
if self.options.clicked
- self.options.clicked(selected)
+ self.options.clicked(selected, $el, e)
# Finds an element inside wrapper element
getElement: (selector) ->
@@ -360,6 +361,8 @@ class GitLabDropdown
# Toggle the dropdown label
if @options.toggleLabel
$(@el).find(".dropdown-toggle-text").text @options.toggleLabel
+ else
+ selectedObject
else
if !value?
field.remove()
@@ -375,7 +378,7 @@ class GitLabDropdown
if @options.toggleLabel
$(@el).find(".dropdown-toggle-text").text @options.toggleLabel(selectedObject)
if value?
- if !field.length
+ if !field.length and fieldName
# Create hidden input for form
input = "<input type='hidden' name='#{fieldName}' value='#{value}' />"
if @options.inputId?
@@ -394,7 +397,7 @@ class GitLabDropdown
selector = ".dropdown-page-one #{selector}"
# simulate a click on the first link
- $(selector).trigger "click"
+ $(selector, @dropdown).trigger "click"
addArrowKeyEvent: ->
ARROW_KEY_CODES = [38, 40]
diff --git a/app/assets/javascripts/issues.js.coffee b/app/assets/javascripts/issues.js.coffee
index b1479bfb449..0d9f2094c2a 100644
--- a/app/assets/javascripts/issues.js.coffee
+++ b/app/assets/javascripts/issues.js.coffee
@@ -26,6 +26,20 @@
$(".selected_issue").bind "change", Issues.checkChanged
+ # Update state filters if present in page
+ updateStateFilters: ->
+ stateFilters = $('.issues-state-filters')
+ newParams = {}
+ paramKeys = ['author_id', 'label_name', 'milestone_title', 'assignee_id', 'issue_search']
+
+ for paramKey in paramKeys
+ newParams[paramKey] = gl.utils.getUrlParameter(paramKey) or ''
+
+ if stateFilters.length
+ stateFilters.find('a').each ->
+ initialUrl = $(this).attr 'href'
+ $(this).attr 'href', gl.utils.mergeUrlParams(newParams, initialUrl)
+
# Make sure we trigger ajax request only after user stop typing
initSearch: ->
@timer = null
@@ -54,6 +68,7 @@
# Change url so if user reload a page - search results are saved
history.replaceState {page: issuesUrl}, document.title, issuesUrl
Issues.reload()
+ Issues.updateStateFilters()
dataType: "json"
checkChanged: ->
diff --git a/app/assets/javascripts/lib/url_utility.js.coffee b/app/assets/javascripts/lib/url_utility.js.coffee
new file mode 100644
index 00000000000..abd556e0b4e
--- /dev/null
+++ b/app/assets/javascripts/lib/url_utility.js.coffee
@@ -0,0 +1,31 @@
+((w) ->
+
+ w.gl ?= {}
+ w.gl.utils ?= {}
+
+ w.gl.utils.getUrlParameter = (sParam) ->
+ sPageURL = decodeURIComponent(window.location.search.substring(1))
+ sURLVariables = sPageURL.split('&')
+ sParameterName = undefined
+ i = 0
+ while i < sURLVariables.length
+ sParameterName = sURLVariables[i].split('=')
+ if sParameterName[0] is sParam
+ return if sParameterName[1] is undefined then true else sParameterName[1]
+ i++
+
+ # #
+ # @param {Object} params - url keys and value to merge
+ # @param {String} url
+ # #
+ w.gl.utils.mergeUrlParams = (params, url) ->
+ newUrl = decodeURIComponent(url)
+ for paramName, paramValue of params
+ pattern = new RegExp "\\b(#{paramName}=).*?(&|$)"
+ if url.search(pattern) >= 0
+ newUrl = newUrl.replace pattern, "$1#{paramValue}$2"
+ else
+ newUrl = "#{newUrl}#{(if newUrl.indexOf('?') > 0 then '&' else '?')}#{paramName}=#{paramValue}"
+ newUrl
+
+) window
diff --git a/app/assets/javascripts/search_autocomplete.js.coffee b/app/assets/javascripts/search_autocomplete.js.coffee
index 030655491bf..6a7b4ad1db7 100644
--- a/app/assets/javascripts/search_autocomplete.js.coffee
+++ b/app/assets/javascripts/search_autocomplete.js.coffee
@@ -62,6 +62,8 @@ class @SearchAutocomplete
search:
fields: ['text']
data: @getData.bind(@)
+ selectable: true
+ clicked: @onClick.bind(@)
getData: (term, callback) ->
_this = @
@@ -102,6 +104,8 @@ class @SearchAutocomplete
lastCategory = suggestion.category
data.push
+ id: "#{suggestion.category.toLowerCase()}-#{suggestion.id}"
+ category: suggestion.category
text: suggestion.label
url: suggestion.url
@@ -133,12 +137,19 @@ class @SearchAutocomplete
}
bindEvents: ->
+ $(document).on 'click', @onDocumentClick
@searchInput.on 'keydown', @onSearchInputKeyDown
@searchInput.on 'keyup', @onSearchInputKeyUp
@searchInput.on 'click', @onSearchInputClick
@searchInput.on 'focus', @onSearchInputFocus
- @searchInput.on 'blur', @onSearchInputBlur
- @clearInput.on 'click', @onRemoveLocationClick
+ @clearInput.on 'click', @onClearInputClick
+
+ onDocumentClick: (e) =>
+ # If clicking outside the search box
+ # And search input is not focused
+ # And we are not clicking inside a suggestion
+ if not $.contains(@dropdown[0], e.target) and @isFocused and not $(e.target).parents('ul').length
+ @onSearchInputBlur()
enableAutocomplete: ->
# No need to enable anything if user is not logged in
@@ -181,6 +192,8 @@ class @SearchAutocomplete
# We should display the menu only when input is not empty
@enableAutocomplete()
+ @wrap.toggleClass 'has-value', !!e.target.value
+
# Avoid falsy value to be returned
return
@@ -189,27 +202,20 @@ class @SearchAutocomplete
e.stopImmediatePropagation()
onSearchInputFocus: =>
+ @isFocused = true
@wrap.addClass('search-active')
- onRemoveLocationClick: (e) =>
+ onClearInputClick: (e) =>
e.preventDefault()
- @removeLocationBadge()
@searchInput.val('').focus()
- @skipBlurEvent = true
onSearchInputBlur: (e) =>
- @skipBlurEvent = false
-
- # We should wait to make sure we are not clearing the input instead
- setTimeout( =>
- return if @skipBlurEvent
+ @isFocused = false
+ @wrap.removeClass('search-active')
- @wrap.removeClass('search-active')
-
- # If input is blank then restore state
- if @searchInput.val() is ''
- @restoreOriginalState()
- , 150)
+ # If input is blank then restore state
+ if @searchInput.val() is ''
+ @restoreOriginalState()
addLocationBadge: (item) ->
category = if item.category? then "#{item.category}: " else ''
@@ -268,3 +274,23 @@ class @SearchAutocomplete
<li><a class='dropdown-menu-empty-link is-focused'>Loading...</a></li>
</ul>"
@dropdownContent.html(html)
+
+ onClick: (item, $el, e) ->
+ if location.pathname.indexOf(item.url) isnt -1
+ e.preventDefault()
+ if not @badgePresent
+ if item.category is 'Projects'
+ @projectInputEl.val(item.id)
+ @addLocationBadge(
+ value: 'This project'
+ )
+
+ if item.category is 'Groups'
+ @groupInputEl.val(item.id)
+ @addLocationBadge(
+ value: 'This group'
+ )
+
+ $el.removeClass('is-active')
+ @disableAutocomplete()
+ @searchInput.val('').focus()
diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss
index c2defd31884..8d3ad934a50 100644
--- a/app/assets/stylesheets/framework/variables.scss
+++ b/app/assets/stylesheets/framework/variables.scss
@@ -104,9 +104,9 @@ $orange-light: rgba(252, 109, 38, 0.80);
$orange-normal: #e75e40;
$orange-dark: #ce5237;
-$red-light: #f06559;
-$red-normal: #e52c5a;
-$red-dark: #d22852;
+$red-light: #e52c5a;
+$red-normal: #d22852;
+$red-dark: darken($red-normal, 5%);
$border-white-light: #f1f2f4;
$border-white-normal: #d6dae2;
@@ -128,9 +128,9 @@ $border-orange-light: #fc6d26;
$border-orange-normal: #ce5237;
$border-orange-dark: #c14e35;
-$border-red-light: #f24f41;
-$border-red-normal: #d22852;
-$border-red-dark: #ca264f;
+$border-red-light: #d22852;
+$border-red-normal: #ca264f;
+$border-red-dark: darken($border-red-normal, 5%);
$help-well-bg: #fafafa;
$help-well-border: #e5e5e5;
@@ -201,14 +201,14 @@ $award-emoji-new-btn-icon-color: #dcdcdc;
/*
* Search Box
*/
-$search-input-border-color: $dropdown-input-focus-border;
+$search-input-border-color: rgba(#4688f1, .8);
$search-input-focus-shadow-color: $dropdown-input-focus-shadow;
-$search-input-width: $dropdown-width;
+$search-input-width: 244px;
$location-badge-color: #aaa;
$location-badge-bg: $gray-normal;
+$location-badge-active-bg: #4f91f8;
$location-icon-color: #e7e9ed;
-$location-active-color: $gl-text-color;
-$location-active-bg: $search-input-border-color;
+$location-icon-active-color: #807e7e;
/*
* Notes
diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss
index 4e6aa8cd1a6..fcca9d4faf5 100644
--- a/app/assets/stylesheets/pages/projects.scss
+++ b/app/assets/stylesheets/pages/projects.scss
@@ -315,7 +315,7 @@ pre.light-well {
}
.git-empty {
- margin: 0 7px;
+ margin: 0 7px 7px;
h5 {
color: #5c5d5e;
@@ -401,7 +401,7 @@ pre.light-well {
}
.commit_short_id {
- margin-right: 5px;
+ margin: 0 5px;
color: $gl-link-color;
font-weight: 600;
}
diff --git a/app/assets/stylesheets/pages/search.scss b/app/assets/stylesheets/pages/search.scss
index 3c74d25beb0..f0f3744c6fa 100644
--- a/app/assets/stylesheets/pages/search.scss
+++ b/app/assets/stylesheets/pages/search.scss
@@ -135,25 +135,25 @@
.location-badge {
@include transition(all .15s);
- background-color: $location-active-bg;
+ background-color: $location-badge-active-bg;
color: $white-light;
}
.search-input-wrap {
i {
- color: $location-active-color;
+ color: $location-icon-active-color;
}
}
+ }
- &.has-location-badge {
- .search-icon {
- display: none;
- }
+ &.has-value {
+ .search-icon {
+ display: none;
+ }
- .clear-icon {
- cursor: pointer;
- display: block;
- }
+ .clear-icon {
+ cursor: pointer;
+ display: block;
}
}
diff --git a/app/assets/stylesheets/pages/status.scss b/app/assets/stylesheets/pages/status.scss
index 5e5e38a0ba6..dbb6daf0d70 100644
--- a/app/assets/stylesheets/pages/status.scss
+++ b/app/assets/stylesheets/pages/status.scss
@@ -1,4 +1,4 @@
-.container-fluid .content {
+.container-fluid {
.ci-status {
padding: 2px 7px;
margin-right: 5px;
diff --git a/app/models/project_services/builds_email_service.rb b/app/models/project_services/builds_email_service.rb
index f6313255cbb..f9f04838766 100644
--- a/app/models/project_services/builds_email_service.rb
+++ b/app/models/project_services/builds_email_service.rb
@@ -50,12 +50,15 @@ class BuildsEmailService < Service
def execute(push_data)
return unless supported_events.include?(push_data[:object_kind])
+ return unless should_build_be_notified?(push_data)
- if should_build_be_notified?(push_data)
+ recipients = all_recipients(push_data)
+
+ if recipients.any?
BuildEmailWorker.perform_async(
push_data[:build_id],
- all_recipients(push_data),
- push_data,
+ recipients,
+ push_data
)
end
end
@@ -84,7 +87,7 @@ class BuildsEmailService < Service
end
def all_recipients(data)
- all_recipients = recipients.split(',')
+ all_recipients = recipients.split(',').compact.reject(&:blank?)
if add_pusher? && data[:user][:email]
all_recipients << "#{data[:user][:email]}"
diff --git a/app/views/layouts/_search.html.haml b/app/views/layouts/_search.html.haml
index baa93ba4c1d..6b208c3d0bb 100644
--- a/app/views/layouts/_search.html.haml
+++ b/app/views/layouts/_search.html.haml
@@ -21,8 +21,8 @@
%a.is-focused.dropdown-menu-empty-link
Loading...
= dropdown_loading
- %i.search-icon
- %i.clear-icon.js-clear-input
+ %i.search-icon
+ %i.clear-icon.js-clear-input
= hidden_field_tag :group_id, @group.try(:id)
= hidden_field_tag :project_id, @project && @project.persisted? ? @project.id : '', id: 'search_project_id'
diff --git a/app/views/projects/notes/_note.html.haml b/app/views/projects/notes/_note.html.haml
index 34fe1743f4b..a681d6dece4 100644
--- a/app/views/projects/notes/_note.html.haml
+++ b/app/views/projects/notes/_note.html.haml
@@ -18,7 +18,7 @@
= 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 danger' do
+ = 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('trash-o')
.note-body{class: note_editable?(note) ? 'js-task-list-container' : ''}
.note-text