summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacob Schatz <jschatz1@gmail.com>2016-03-23 22:13:31 +0000
committerJacob Schatz <jschatz1@gmail.com>2016-03-23 22:13:31 +0000
commit4a4a79aa9eb190c44d73dc44f22c88ec5613ac58 (patch)
tree076d7b430cf5fb6ad2fc6a8d242ab0edc10dc0d9
parent31ba9c303bfec5f7ca440067b463126af8f41394 (diff)
parent0141d3654ffd535366a4405c0ee58f9a6998c58f (diff)
downloadgitlab-ce-restrict_avatar_upload_to_image_files.tar.gz
Merge branch 'dropdown-alignment-fixes' into 'master' restrict_avatar_upload_to_image_files
Dropdown pixel perfect :tada: Closes #14333, #14331, #14472, #14515 See merge request !3337
-rw-r--r--app/assets/javascripts/gl_dropdown.js.coffee39
-rw-r--r--app/assets/javascripts/labels_select.js.coffee86
-rw-r--r--app/assets/javascripts/users_select.js.coffee35
-rw-r--r--app/assets/stylesheets/framework/dropdowns.scss45
-rw-r--r--app/assets/stylesheets/framework/variables.scss5
-rw-r--r--app/assets/stylesheets/pages/labels.scss33
-rw-r--r--app/helpers/dropdowns_helper.rb3
-rw-r--r--app/views/shared/issuable/_label_dropdown.html.haml14
-rw-r--r--features/steps/dashboard/issues.rb4
9 files changed, 196 insertions, 68 deletions
diff --git a/app/assets/javascripts/gl_dropdown.js.coffee b/app/assets/javascripts/gl_dropdown.js.coffee
index 960585245d7..4b78bcde774 100644
--- a/app/assets/javascripts/gl_dropdown.js.coffee
+++ b/app/assets/javascripts/gl_dropdown.js.coffee
@@ -1,13 +1,29 @@
class GitLabDropdownFilter
BLUR_KEYCODES = [27, 40]
+ HAS_VALUE_CLASS = "has-value"
- constructor: (@dropdown, @options) ->
- @input = @dropdown.find(".dropdown-input .dropdown-input-field")
+ constructor: (@input, @options) ->
+ $inputContainer = @input.parent()
+ $clearButton = $inputContainer.find('.js-dropdown-input-clear')
+
+ # Clear click
+ $clearButton.on 'click', (e) =>
+ e.preventDefault()
+ e.stopPropagation()
+ @input
+ .val('')
+ .trigger('keyup')
+ .focus()
# Key events
timeout = ""
@input.on "keyup", (e) =>
- if e.keyCode is 13 && @input.val() isnt ""
+ if @input.val() isnt "" and !$inputContainer.hasClass HAS_VALUE_CLASS
+ $inputContainer.addClass HAS_VALUE_CLASS
+ else if @input.val() is "" and $inputContainer.hasClass HAS_VALUE_CLASS
+ $inputContainer.removeClass HAS_VALUE_CLASS
+
+ if e.keyCode is 13 and @input.val() isnt ""
if @options.enterCallback
@options.enterCallback()
return
@@ -95,7 +111,9 @@ class GitLabDropdown
# Init filiterable
if @options.filterable
- @filter = new GitLabDropdownFilter @dropdown,
+ @input = @dropdown.find('.dropdown-input .dropdown-input-field')
+
+ @filter = new GitLabDropdownFilter @input,
remote: @options.filterRemote
query: @options.data
keys: @options.search.fields
@@ -103,6 +121,7 @@ class GitLabDropdown
return @fullData
callback: (data) =>
@parseData data
+ @highlightRow 1
enterCallback: =>
@selectFirstRow()
@@ -224,11 +243,19 @@ class GitLabDropdown
noResults: ->
html = "<li>"
- html += "<a href='#' class='is-focused'>"
+ html += "<a href='#' class='dropdown-menu-empty-link is-focused'>"
html += "No matching results."
html += "</a>"
html += "</li>"
+ highlightRow: (index) ->
+ if @input.val() isnt ""
+ selector = '.dropdown-content li:first-child a'
+ if @dropdown.find(".dropdown-toggle-page").length
+ selector = ".dropdown-page-one .dropdown-content li:first-child a"
+
+ $(selector).addClass 'is-focused'
+
rowClicked: (el) ->
fieldName = @options.fieldName
field = @dropdown.parent().find("input[name='#{fieldName}']")
@@ -272,7 +299,7 @@ class GitLabDropdown
if @dropdown.find(".dropdown-toggle-page").length
selector = ".dropdown-page-one .dropdown-content li:first-child a"
- # similute a click on the first link
+ # simulate a click on the first link
$(selector).trigger "click"
$.fn.glDropdown = (opts) ->
diff --git a/app/assets/javascripts/labels_select.js.coffee b/app/assets/javascripts/labels_select.js.coffee
index f3cb1e3bc09..e08648d583b 100644
--- a/app/assets/javascripts/labels_select.js.coffee
+++ b/app/assets/javascripts/labels_select.js.coffee
@@ -6,7 +6,7 @@ class @LabelsSelect
labelUrl = $dropdown.data('labels')
selectedLabel = $dropdown.data('selected')
if selectedLabel
- selectedLabel = selectedLabel.split(',')
+ selectedLabel = selectedLabel.toString().split(',')
newLabelField = $('#new_label_name')
newColorField = $('#new_label_color')
showNo = $dropdown.data('show-no')
@@ -14,38 +14,81 @@ class @LabelsSelect
defaultLabel = $dropdown.data('default-label')
if newLabelField.length
+ $newLabelCreateButton = $('.js-new-label-btn')
+ $colorPreview = $('.js-dropdown-label-color-preview')
$newLabelError = $dropdown.parent().find('.js-label-error')
$newLabelError.hide()
+ # Suggested colors in the dropdown to chose from pre-chosen colors
$('.suggest-colors-dropdown a').on 'click', (e) ->
e.preventDefault()
e.stopPropagation()
- newColorField.val $(this).data('color')
- $('.js-dropdown-label-color-preview')
+ newColorField
+ .val($(this).data('color'))
+ .trigger('change')
+ $colorPreview
.css 'background-color', $(this).data('color')
+ .parent()
.addClass 'is-active'
- $('.js-new-label-btn').on 'click', (e) ->
+ # Cancel button takes back to first page
+ resetForm = ->
+ newLabelField
+ .val ''
+ .trigger 'change'
+ newColorField
+ .val ''
+ .trigger 'change'
+ $colorPreview
+ .css 'background-color', ''
+ .parent()
+ .removeClass 'is-active'
+
+ $('.dropdown-menu-back').on 'click', ->
+ resetForm()
+
+ $('.js-cancel-label-btn').on 'click', (e) ->
e.preventDefault()
e.stopPropagation()
+ resetForm()
+ $('.dropdown-menu-back', $dropdown.parent()).trigger 'click'
+ # Listen for change and keyup events on label and color field
+ # This allows us to enable the button when ready
+ enableLabelCreateButton = ->
if newLabelField.val() isnt '' and newColorField.val() isnt ''
- $newLabelError.hide()
- $('.js-new-label-btn').disable()
-
- # Create new label with API
- Api.newLabel projectId, {
- name: newLabelField.val()
- color: newColorField.val()
- }, (label) ->
- $('.js-new-label-btn').enable()
-
- if label.message?
- $newLabelError
- .text label.message
- .show()
- else
- $('.dropdown-menu-back', $dropdown.parent()).trigger 'click'
+ $newLabelCreateButton.enable()
+ else
+ $newLabelCreateButton.disable()
+
+ newLabelField.on 'keyup change', enableLabelCreateButton
+
+ newColorField.on 'keyup change', enableLabelCreateButton
+
+ # Send the API call to create the label
+ $newLabelCreateButton
+ .disable()
+ .on 'click', (e) ->
+ e.preventDefault()
+ e.stopPropagation()
+
+ if newLabelField.val() isnt '' and newColorField.val() isnt ''
+ $newLabelError.hide()
+ $('.js-new-label-btn').disable()
+
+ # Create new label with API
+ Api.newLabel projectId, {
+ name: newLabelField.val()
+ color: newColorField.val()
+ }, (label) ->
+ $('.js-new-label-btn').enable()
+
+ if label.message?
+ $newLabelError
+ .text label.message
+ .show()
+ else
+ $('.dropdown-menu-back', $dropdown.parent()).trigger 'click'
$dropdown.glDropdown(
data: (term, callback) ->
@@ -78,8 +121,11 @@ class @LabelsSelect
else
selected = if label.title is selectedLabel then 'is-active' else ''
+ color = if label.color? then "<span class='dropdown-label-box' style='background-color: #{label.color}'></span>" else ""
+
"<li>
<a href='#' class='#{selected}'>
+ #{color}
#{label.title}
</a>
</li>"
diff --git a/app/assets/javascripts/users_select.js.coffee b/app/assets/javascripts/users_select.js.coffee
index 3d6452d2f46..84193400890 100644
--- a/app/assets/javascripts/users_select.js.coffee
+++ b/app/assets/javascripts/users_select.js.coffee
@@ -30,6 +30,7 @@ class @UsersSelect
if showNullUser
showDivider += 1
users.unshift(
+ beforeDivider: true
name: 'Unassigned',
id: 0
)
@@ -39,6 +40,7 @@ class @UsersSelect
name = showAnyUser
name = 'Any User' if name == true
anyUser = {
+ beforeDivider: true
name: name,
id: null
}
@@ -75,20 +77,27 @@ class @UsersSelect
selected = if user.id is selectedId then "is-active" else ""
img = ""
- if avatar
- img = "<img src='#{avatar}' class='avatar avatar-inline' width='30' />"
-
- "<li>
- <a href='#' class='dropdown-menu-user-link #{selected}'>
- #{img}
- <strong class='dropdown-menu-user-full-name'>
+ if user.beforeDivider?
+ "<li>
+ <a href='#' class='#{selected}'>
#{user.name}
- </strong>
- <span class='dropdown-menu-user-username'>
- #{username}
- </span>
- </a>
- </li>"
+ </a>
+ </li>"
+ else
+ if avatar
+ img = "<img src='#{avatar}' class='avatar avatar-inline' width='30' />"
+
+ "<li>
+ <a href='#' class='dropdown-menu-user-link #{selected}'>
+ #{img}
+ <strong class='dropdown-menu-user-full-name'>
+ #{user.name}
+ </strong>
+ <span class='dropdown-menu-user-username'>
+ #{username}
+ </span>
+ </a>
+ </li>"
)
$('.ajax-users-select').each (i, select) =>
diff --git a/app/assets/stylesheets/framework/dropdowns.scss b/app/assets/stylesheets/framework/dropdowns.scss
index d92cf6e6c44..2d616fc660c 100644
--- a/app/assets/stylesheets/framework/dropdowns.scss
+++ b/app/assets/stylesheets/framework/dropdowns.scss
@@ -130,6 +130,12 @@
text-decoration: none;
outline: 0;
}
+
+ &.dropdown-menu-empty-link {
+ &.is-focused {
+ background-color: $dropdown-empty-row-bg;
+ }
+ }
}
}
@@ -183,7 +189,7 @@
}
.dropdown-select {
- width: 280px;
+ width: 300px;
}
.dropdown-menu-align-right {
@@ -237,7 +243,7 @@
.dropdown-title-button {
position: absolute;
- top: -1px;
+ top: 0;
padding: 0;
color: $dropdown-title-btn-color;
font-size: 14px;
@@ -270,6 +276,22 @@
font-size: 12px;
pointer-events: none;
}
+
+ .dropdown-input-clear {
+ display: none;
+ cursor: pointer;
+ pointer-events: all;
+ }
+
+ &.has-value {
+ .dropdown-input-clear {
+ display: block;
+ }
+
+ .dropdown-input-search {
+ display: none;
+ }
+ }
}
.dropdown-input-field {
@@ -286,13 +308,13 @@
border-color: $dropdown-input-focus-border;
box-shadow: 0 0 4px $dropdown-input-focus-shadow;
- + .fa {
+ ~ .fa {
color: $dropdown-link-color;
}
}
&:hover {
- + .fa {
+ ~ .fa {
color: $dropdown-link-color;
}
}
@@ -338,11 +360,12 @@
}
}
-.dropdown-menu-labels {
- .label {
- position: relative;
- width: 30px;
- margin-right: 5px;
- text-indent: -99999px;
- }
+.dropdown-label-box {
+ position: relative;
+ top: 3px;
+ margin-right: 5px;
+ display: inline-block;
+ width: 15px;
+ height: 15px;
+ border-radius: $border-radius-base;
}
diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss
index be626678bd7..61e0dd4d672 100644
--- a/app/assets/stylesheets/framework/variables.scss
+++ b/app/assets/stylesheets/framework/variables.scss
@@ -168,13 +168,14 @@ $regular_font: 'Source Sans Pro', "Helvetica Neue", Helvetica, Arial, sans-serif
*/
$dropdown-bg: #fff;
$dropdown-link-color: #555;
-$dropdown-link-hover-bg: rgba(#000, .04);
+$dropdown-link-hover-bg: $row-hover;
+$dropdown-empty-row-bg: rgba(#000, .04);
$dropdown-border-color: rgba(#000, .1);
$dropdown-shadow-color: rgba(#000, .1);
$dropdown-divider-color: rgba(#000, .1);
$dropdown-header-color: #959494;
$dropdown-title-btn-color: #bfbfbf;
-$dropdown-input-color: #c7c7c7;
+$dropdown-input-color: #555;
$dropdown-input-focus-border: rgb(58, 171, 240);
$dropdown-input-focus-shadow: rgba(#000, .2);
$dropdown-loading-bg: rgba(#fff, .6);
diff --git a/app/assets/stylesheets/pages/labels.scss b/app/assets/stylesheets/pages/labels.scss
index 3c13573c8fe..4e02ec4e891 100644
--- a/app/assets/stylesheets/pages/labels.scss
+++ b/app/assets/stylesheets/pages/labels.scss
@@ -9,28 +9,45 @@
}
&.suggest-colors-dropdown {
- margin-bottom: 5px;
+ margin-top: 10px;
+ margin-bottom: 10px;
+ border-radius: $border-radius-base;
+ overflow: hidden;
a {
@include border-radius(0);
- width: 36.7px;
+ width: (100% / 7);
margin-right: 0;
margin-bottom: -5px;
}
}
}
-.dropdown-label-color-preview {
- display: none;
- margin-top: 5px;
- width: 100%;
- height: 25px;
+.dropdown-new-label {
+ .dropdown-content {
+ max-height: 260px;
+ }
+}
+
+.dropdown-label-color-input {
+ position: relative;
+ margin-bottom: 10px;
&.is-active {
- display: block;
+ padding-left: 32px;
}
}
+.dropdown-label-color-preview {
+ position: absolute;
+ left: 0;
+ top: 0;
+ width: 32px;
+ height: 32px;
+ border-top-left-radius: $border-radius-base;
+ border-bottom-left-radius: $border-radius-base;
+}
+
.label-row {
.label {
padding: 9px;
diff --git a/app/helpers/dropdowns_helper.rb b/app/helpers/dropdowns_helper.rb
index ceff1fbb161..316a10b7da3 100644
--- a/app/helpers/dropdowns_helper.rb
+++ b/app/helpers/dropdowns_helper.rb
@@ -70,7 +70,8 @@ module DropdownsHelper
def dropdown_filter(placeholder)
content_tag :div, class: "dropdown-input" do
filter_output = search_field_tag nil, nil, class: "dropdown-input-field", placeholder: placeholder
- filter_output << icon('search')
+ filter_output << icon('search', class: "dropdown-input-search")
+ filter_output << icon('times', class: "dropdown-input-clear js-dropdown-input-clear", role: "button")
filter_output.html_safe
end
diff --git a/app/views/shared/issuable/_label_dropdown.html.haml b/app/views/shared/issuable/_label_dropdown.html.haml
index 186087e8f89..006a34a11e3 100644
--- a/app/views/shared/issuable/_label_dropdown.html.haml
+++ b/app/views/shared/issuable/_label_dropdown.html.haml
@@ -24,17 +24,21 @@
- else
View labels
- if can? current_user, :admin_label, @project and @project
- .dropdown-page-two
+ .dropdown-page-two.dropdown-new-label
= dropdown_title("Create new label", back: true)
= dropdown_content do
.dropdown-labels-error.js-label-error
- %input#new_label_color{type: "hidden"}
%input#new_label_name.dropdown-input-field{type: "text", placeholder: "Name new label"}
- .dropdown-label-color-preview.js-dropdown-label-color-preview
.suggest-colors.suggest-colors-dropdown
- suggested_colors.each do |color|
= link_to '#', style: "background-color: #{color}", data: { color: color } do
&nbsp
- %button.btn.btn-primary.js-new-label-btn{type: "button"}
- Create
+ .dropdown-label-color-input
+ .dropdown-label-color-preview.js-dropdown-label-color-preview
+ %input#new_label_color.dropdown-input-field{ type: "text" }
+ .clearfix
+ %button.btn.btn-primary.pull-left.js-new-label-btn{type: "button"}
+ Create
+ %button.btn.btn-default.pull-right.js-cancel-label-btn{type: "button"}
+ Cancel
= dropdown_loading
diff --git a/features/steps/dashboard/issues.rb b/features/steps/dashboard/issues.rb
index f4a56865532..93aa77589be 100644
--- a/features/steps/dashboard/issues.rb
+++ b/features/steps/dashboard/issues.rb
@@ -43,10 +43,10 @@ class Spinach::Features::DashboardIssues < Spinach::FeatureSteps
step 'I click "All" link' do
find('.js-author-search').click
- find('.dropdown-menu-user-full-name', match: :first).click
+ find('.dropdown-content a', match: :first).click
find('.js-assignee-search').click
- find('.dropdown-menu-user-full-name', match: :first).click
+ find('.dropdown-content a', match: :first).click
end
def should_see(issue)