2016-03-07 17:17:11 +00:00
|
|
|
class @LabelsSelect
|
|
|
|
constructor: ->
|
|
|
|
$('.js-label-select').each (i, dropdown) ->
|
2016-03-18 10:12:52 +00:00
|
|
|
$dropdown = $(dropdown)
|
|
|
|
projectId = $dropdown.data('project-id')
|
|
|
|
labelUrl = $dropdown.data('labels')
|
2016-03-12 20:37:02 +00:00
|
|
|
issueUpdateURL = $dropdown.data('issueUpdate')
|
2016-03-18 10:12:52 +00:00
|
|
|
selectedLabel = $dropdown.data('selected')
|
2016-04-07 18:57:21 +00:00
|
|
|
if selectedLabel? and not $dropdown.hasClass 'js-multiselect'
|
2016-03-13 19:08:42 +00:00
|
|
|
selectedLabel = selectedLabel.split(',')
|
2016-04-18 17:49:23 +00:00
|
|
|
newLabelField = $('#new_label_name')
|
|
|
|
newColorField = $('#new_label_color')
|
2016-03-18 10:12:52 +00:00
|
|
|
showNo = $dropdown.data('show-no')
|
|
|
|
showAny = $dropdown.data('show-any')
|
2016-03-18 12:21:07 +00:00
|
|
|
defaultLabel = $dropdown.data('default-label')
|
2016-03-17 13:14:46 +00:00
|
|
|
abilityName = $dropdown.data('ability-name')
|
2016-03-12 20:37:02 +00:00
|
|
|
$selectbox = $dropdown.closest('.selectbox')
|
|
|
|
$block = $selectbox.closest('.block')
|
2016-04-09 04:09:09 +00:00
|
|
|
$form = $dropdown.closest('form')
|
2016-03-26 15:43:42 +00:00
|
|
|
$sidebarCollapsedValue = $block.find('.sidebar-collapsed-icon span')
|
2016-03-12 20:37:02 +00:00
|
|
|
$value = $block.find('.value')
|
2016-04-18 17:49:23 +00:00
|
|
|
$newLabelError = $('.js-label-error')
|
|
|
|
$colorPreview = $('.js-dropdown-label-color-preview')
|
|
|
|
$newLabelCreateButton = $('.js-new-label-btn')
|
2016-04-15 18:01:46 +00:00
|
|
|
|
|
|
|
$newLabelError.hide()
|
2016-03-12 20:37:02 +00:00
|
|
|
$loading = $block.find('.block-loading').fadeOut()
|
2016-03-08 11:23:54 +00:00
|
|
|
|
2016-03-19 15:39:34 +00:00
|
|
|
issueURLSplit = issueUpdateURL.split('/') if issueUpdateURL?
|
|
|
|
if issueUpdateURL
|
2016-03-13 19:08:42 +00:00
|
|
|
labelHTMLTemplate = _.template(
|
2016-03-20 00:19:51 +00:00
|
|
|
'<% _.each(labels, function(label){ %>
|
2016-04-19 17:41:08 +00:00
|
|
|
<a href="<%= ["",issueURLSplit[1], issueURLSplit[2],""].join("/") %>issues?label_name=<%= _.escape(label.title) %>">
|
2016-04-21 07:50:15 +00:00
|
|
|
<span class="label has-tooltip color-label" title="<%= _.escape(label.description) %>" style="background-color: <%= label.color %>; color: <%= label.text_color %>;">
|
2016-04-19 17:41:08 +00:00
|
|
|
<%= _.escape(label.title) %>
|
2016-03-20 00:19:51 +00:00
|
|
|
</span>
|
|
|
|
</a>
|
|
|
|
<% }); %>'
|
2016-04-19 17:41:08 +00:00
|
|
|
)
|
2016-03-14 19:37:16 +00:00
|
|
|
labelNoneHTMLTemplate = _.template('<div class="light">None</div>')
|
2016-03-13 19:08:42 +00:00
|
|
|
|
2016-04-15 18:01:46 +00:00
|
|
|
if newLabelField.length
|
2016-04-12 04:05:49 +00:00
|
|
|
|
|
|
|
# Suggested colors in the dropdown to chose from pre-chosen colors
|
2016-03-13 19:08:42 +00:00
|
|
|
$('.suggest-colors-dropdown a').on "click", (e) ->
|
2016-03-08 11:23:54 +00:00
|
|
|
e.preventDefault()
|
|
|
|
e.stopPropagation()
|
2016-03-23 13:29:41 +00:00
|
|
|
newColorField
|
|
|
|
.val($(this).data('color'))
|
|
|
|
.trigger('change')
|
|
|
|
$colorPreview
|
2016-03-18 10:12:52 +00:00
|
|
|
.css 'background-color', $(this).data('color')
|
2016-03-22 09:45:05 +00:00
|
|
|
.parent()
|
2016-03-08 11:23:54 +00:00
|
|
|
.addClass 'is-active'
|
|
|
|
|
2016-03-23 13:29:41 +00:00
|
|
|
# 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()
|
|
|
|
|
2016-03-22 09:45:05 +00:00
|
|
|
$('.js-cancel-label-btn').on 'click', (e) ->
|
|
|
|
e.preventDefault()
|
|
|
|
e.stopPropagation()
|
2016-03-23 13:29:41 +00:00
|
|
|
resetForm()
|
2016-03-22 09:45:05 +00:00
|
|
|
$('.dropdown-menu-back', $dropdown.parent()).trigger 'click'
|
|
|
|
|
2016-03-23 13:29:41 +00:00
|
|
|
# Listen for change and keyup events on label and color field
|
|
|
|
# This allows us to enable the button when ready
|
|
|
|
enableLabelCreateButton = ->
|
2016-03-18 10:12:52 +00:00
|
|
|
if newLabelField.val() isnt '' and newColorField.val() isnt ''
|
2016-03-17 19:15:47 +00:00
|
|
|
$newLabelError.hide()
|
2016-03-23 13:29:41 +00:00
|
|
|
$newLabelCreateButton.enable()
|
|
|
|
else
|
|
|
|
$newLabelCreateButton.disable()
|
|
|
|
|
2016-04-15 18:01:46 +00:00
|
|
|
saveLabel = ->
|
|
|
|
# Create new label with API
|
|
|
|
Api.newLabel projectId, {
|
|
|
|
name: newLabelField.val()
|
|
|
|
color: newColorField.val()
|
|
|
|
}, (label) ->
|
|
|
|
$newLabelCreateButton.enable()
|
|
|
|
|
|
|
|
if label.message?
|
|
|
|
$newLabelError
|
|
|
|
.text label.message
|
|
|
|
.show()
|
|
|
|
else
|
|
|
|
$('.dropdown-menu-back', $dropdown.parent()).trigger 'click'
|
|
|
|
|
2016-03-23 13:29:41 +00:00
|
|
|
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()
|
2016-04-15 18:01:46 +00:00
|
|
|
saveLabel()
|
2016-03-07 17:17:11 +00:00
|
|
|
|
2016-03-17 19:15:47 +00:00
|
|
|
saveLabelData = ->
|
|
|
|
selected = $dropdown
|
|
|
|
.closest('.selectbox')
|
|
|
|
.find("input[name='#{$dropdown.data('field-name')}']")
|
|
|
|
.map(->
|
|
|
|
@value
|
|
|
|
).get()
|
|
|
|
data = {}
|
|
|
|
data[abilityName] = {}
|
|
|
|
data[abilityName].label_ids = selected
|
|
|
|
if not selected.length
|
|
|
|
data[abilityName].label_ids = ['']
|
|
|
|
$loading.fadeIn()
|
2016-03-27 15:04:51 +00:00
|
|
|
$dropdown.trigger('loading.gl.dropdown')
|
2016-03-17 19:15:47 +00:00
|
|
|
$.ajax(
|
|
|
|
type: 'PUT'
|
2016-03-19 15:39:34 +00:00
|
|
|
url: issueUpdateURL
|
2016-03-18 18:35:39 +00:00
|
|
|
dataType: 'JSON'
|
2016-03-17 19:15:47 +00:00
|
|
|
data: data
|
|
|
|
).done (data) ->
|
|
|
|
$loading.fadeOut()
|
2016-03-27 15:04:51 +00:00
|
|
|
$dropdown.trigger('loaded.gl.dropdown')
|
2016-03-17 19:15:47 +00:00
|
|
|
$selectbox.hide()
|
2016-03-25 12:00:16 +00:00
|
|
|
data.issueURLSplit = issueURLSplit
|
2016-03-26 15:43:42 +00:00
|
|
|
labelCount = 0
|
|
|
|
if data.labels.length
|
2016-03-17 19:15:47 +00:00
|
|
|
template = labelHTMLTemplate(data)
|
2016-03-26 15:43:42 +00:00
|
|
|
labelCount = data.labels.length
|
|
|
|
else
|
|
|
|
template = labelNoneHTMLTemplate()
|
|
|
|
$value
|
|
|
|
.removeAttr('style')
|
|
|
|
.html(template)
|
|
|
|
$sidebarCollapsedValue.text(labelCount)
|
|
|
|
|
2016-04-11 22:42:51 +00:00
|
|
|
$('.has-tooltip', $value).tooltip(container: 'body')
|
|
|
|
|
2016-03-19 15:39:34 +00:00
|
|
|
$value
|
|
|
|
.find('a')
|
|
|
|
.each((i) ->
|
|
|
|
setTimeout(=>
|
2016-04-09 04:09:09 +00:00
|
|
|
gl.animate.animate($(@), 'pulse')
|
2016-03-19 15:39:34 +00:00
|
|
|
,200 * i
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
2016-03-17 19:15:47 +00:00
|
|
|
|
2016-03-18 10:12:52 +00:00
|
|
|
$dropdown.glDropdown(
|
2016-03-08 09:09:39 +00:00
|
|
|
data: (term, callback) ->
|
2016-03-08 12:32:04 +00:00
|
|
|
$.ajax(
|
|
|
|
url: labelUrl
|
|
|
|
).done (data) ->
|
2016-03-13 19:08:42 +00:00
|
|
|
if $dropdown.hasClass 'js-extra-options'
|
|
|
|
if showNo
|
|
|
|
data.unshift(
|
|
|
|
id: 0
|
|
|
|
title: 'No Label'
|
|
|
|
)
|
|
|
|
|
|
|
|
if showAny
|
|
|
|
data.unshift(
|
|
|
|
isAny: true
|
|
|
|
title: 'Any Label'
|
|
|
|
)
|
|
|
|
|
|
|
|
if data.length > 2
|
|
|
|
data.splice 2, 0, 'divider'
|
2016-03-08 12:32:04 +00:00
|
|
|
callback data
|
2016-03-13 19:08:42 +00:00
|
|
|
|
2016-03-07 17:17:11 +00:00
|
|
|
renderRow: (label) ->
|
2016-04-20 16:52:55 +00:00
|
|
|
removesAll = label.id is 0 or not label.id?
|
2016-04-20 16:23:10 +00:00
|
|
|
|
|
|
|
selectedClass = []
|
2016-04-09 04:09:09 +00:00
|
|
|
if $form.find("input[type='hidden']\
|
2016-04-16 19:56:19 +00:00
|
|
|
[name='#{$dropdown.data('fieldName')}']\
|
2016-04-09 04:09:09 +00:00
|
|
|
[value='#{this.id(label)}']").length
|
2016-04-20 16:23:10 +00:00
|
|
|
selectedClass.push 'is-active'
|
|
|
|
|
|
|
|
if $dropdown.hasClass('js-multiselect') and removesAll
|
|
|
|
selectedClass.push 'dropdown-clear-active'
|
2016-03-08 08:38:16 +00:00
|
|
|
|
2016-03-18 17:11:51 +00:00
|
|
|
color = if label.color? then "<span class='dropdown-label-box' style='background-color: #{label.color}'></span>" else ""
|
|
|
|
|
2016-03-07 17:17:11 +00:00
|
|
|
"<li>
|
2016-04-20 16:23:10 +00:00
|
|
|
<a href='#' class='#{selectedClass.join(' ')}'>
|
2016-03-18 17:11:51 +00:00
|
|
|
#{color}
|
2016-04-19 17:41:08 +00:00
|
|
|
#{_.escape(label.title)}
|
2016-03-07 17:17:11 +00:00
|
|
|
</a>
|
|
|
|
</li>"
|
|
|
|
filterable: true
|
|
|
|
search:
|
2016-03-08 15:18:01 +00:00
|
|
|
fields: ['title']
|
2016-03-07 17:17:11 +00:00
|
|
|
selectable: true
|
2016-03-12 20:37:02 +00:00
|
|
|
|
2016-04-14 14:26:53 +00:00
|
|
|
toggleLabel: (selected, el) ->
|
|
|
|
selected_labels = $('.js-label-select').siblings('.dropdown-menu-labels').find('.is-active')
|
|
|
|
|
2016-04-12 08:32:12 +00:00
|
|
|
if selected and selected.title?
|
2016-04-19 16:22:55 +00:00
|
|
|
if selected_labels.length > 1
|
2016-04-14 14:26:53 +00:00
|
|
|
"#{selected.title} +#{selected_labels.length - 1} more"
|
|
|
|
else
|
|
|
|
selected.title
|
|
|
|
else if not selected and selected_labels.length isnt 0
|
|
|
|
if selected_labels.length > 1
|
|
|
|
"#{$(selected_labels[0]).text()} +#{selected_labels.length - 1} more"
|
|
|
|
else if selected_labels.length is 1
|
|
|
|
$(selected_labels).text()
|
2016-03-15 18:20:22 +00:00
|
|
|
else
|
|
|
|
defaultLabel
|
2016-03-18 10:12:52 +00:00
|
|
|
fieldName: $dropdown.data('field-name')
|
2016-03-07 17:17:11 +00:00
|
|
|
id: (label) ->
|
2016-04-20 16:23:10 +00:00
|
|
|
if $dropdown.hasClass("js-filter-submit") and not label.isAny?
|
2016-04-22 13:32:14 +00:00
|
|
|
_.escape label.title
|
2016-03-12 20:37:02 +00:00
|
|
|
else
|
|
|
|
label.id
|
|
|
|
|
|
|
|
hidden: ->
|
2016-03-29 14:52:25 +00:00
|
|
|
page = $('body').data 'page'
|
|
|
|
isIssueIndex = page is 'projects:issues:index'
|
2016-04-19 16:22:55 +00:00
|
|
|
isMRIndex = page is 'projects:merge_requests:index'
|
2016-04-14 14:26:53 +00:00
|
|
|
|
2016-03-12 20:37:02 +00:00
|
|
|
$selectbox.hide()
|
2016-03-26 15:43:42 +00:00
|
|
|
# display:block overrides the hide-collapse rule
|
|
|
|
$value.removeAttr('style')
|
2016-03-19 15:39:34 +00:00
|
|
|
if $dropdown.hasClass 'js-multiselect'
|
2016-03-29 14:52:25 +00:00
|
|
|
if $dropdown.hasClass('js-filter-submit') and (isIssueIndex or isMRIndex)
|
2016-04-07 16:47:32 +00:00
|
|
|
selectedLabels = $dropdown
|
|
|
|
.closest('form')
|
2016-04-19 16:22:55 +00:00
|
|
|
.find("input:hidden[name='#{$dropdown.data('fieldName')}']")
|
2016-04-20 16:00:12 +00:00
|
|
|
Issuable.filterResults $dropdown.closest('form')
|
2016-03-29 14:52:25 +00:00
|
|
|
else if $dropdown.hasClass('js-filter-submit')
|
|
|
|
$dropdown.closest('form').submit()
|
|
|
|
else
|
|
|
|
saveLabelData()
|
2016-03-12 20:37:02 +00:00
|
|
|
|
2016-03-14 19:37:16 +00:00
|
|
|
multiSelect: $dropdown.hasClass 'js-multiselect'
|
2016-03-23 16:44:09 +00:00
|
|
|
clicked: (label) ->
|
2016-03-18 10:12:52 +00:00
|
|
|
page = $('body').data 'page'
|
|
|
|
isIssueIndex = page is 'projects:issues:index'
|
2016-04-19 16:22:55 +00:00
|
|
|
isMRIndex = page is 'projects:merge_requests:index'
|
2016-03-18 10:12:52 +00:00
|
|
|
if $dropdown.hasClass('js-filter-submit') and (isIssueIndex or isMRIndex)
|
2016-04-07 16:47:32 +00:00
|
|
|
if not $dropdown.hasClass 'js-multiselect'
|
|
|
|
selectedLabel = label.title
|
2016-04-20 16:00:12 +00:00
|
|
|
Issuable.filterResults $dropdown.closest('form')
|
2016-03-18 10:12:52 +00:00
|
|
|
else if $dropdown.hasClass 'js-filter-submit'
|
|
|
|
$dropdown.closest('form').submit()
|
2016-03-12 20:37:02 +00:00
|
|
|
else
|
2016-03-17 19:15:47 +00:00
|
|
|
if $dropdown.hasClass 'js-multiselect'
|
|
|
|
return
|
|
|
|
else
|
|
|
|
saveLabelData()
|
2016-03-07 17:17:11 +00:00
|
|
|
)
|