diff --git a/app/assets/javascripts/gl_dropdown.js.coffee b/app/assets/javascripts/gl_dropdown.js.coffee
index 960585245d797536149bb4e575903f734fc1bc32..4b78bcde77488edd0c1c8ff375ff4afbf75fc151 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 = "
"
- html += ""
+ html += ""
html += ""
+ 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 f3cb1e3bc09fe5ab6bea71432d0e5b1319147a83..e08648d583b169af9993de3c80da4284d2a46354 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 "" else ""
+
"
+ #{color}
#{label.title}
"
diff --git a/app/assets/javascripts/users_select.js.coffee b/app/assets/javascripts/users_select.js.coffee
index 3d6452d2f4693d36691df7ff987bc257de83d761..84193400890b4f8a19f6fe67146c2101bf68b08c 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 = "
"
-
- "
-
- "
+
+ "
+ else
+ if avatar
+ img = "
"
+
+ "
+
+ "
)
$('.ajax-users-select').each (i, select) =>
diff --git a/app/assets/stylesheets/framework/dropdowns.scss b/app/assets/stylesheets/framework/dropdowns.scss
index d92cf6e6c44f7ca4c1eeaec30e4c01e632a20c38..2d616fc660c520afb058abe39e37f8df17e7fd8f 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 be626678bd7a88e3682007c8fda9e66b9848c5a9..61e0dd4d672b1f6e95704f68df796ea6a3a6e784 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 3c13573c8fe93cee7d0380a0be699468f4d82d38..4e02ec4e89164475eea0bd8f50fcb0ce866a33c6 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 ceff1fbb1618a0d16b1f658a438eabc4e0fc4da5..316a10b7da36ee52b6b349d13d9cce4505670b0d 100644
--- a/app/helpers/dropdowns_helper.rb
+++ b/app/helpers/dropdowns_helper.rb
@@ -70,7 +70,8 @@ def dropdown_title(title, back: false)
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 186087e8f89381a08fa8eb20aaa3a106e7236f9c..006a34a11e3ea387f3e387ff0ef27a46c4112552 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
 
- %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 f4a56865532559da8682fce5469fc6d539a4e237..93aa77589be53982619b5a68514560dcfb67bfc8 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)