summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacob Schatz <jschatz@gitlab.com>2016-07-15 02:29:10 +0000
committerJacob Schatz <jschatz@gitlab.com>2016-07-15 02:29:10 +0000
commitbdb6f1e6fa756ae0db57e0474706685b6115c1e1 (patch)
tree4a41b2125df0c8b956e8060d737adc572049f1bf
parentdfb0b5de3a33cc20f753f8594eb2a5278ede060e (diff)
parentafbd631c78bea27ea7e088c090e947959285a176 (diff)
downloadgitlab-ce-bdb6f1e6fa756ae0db57e0474706685b6115c1e1.tar.gz
Merge branch 'gl-dropdown-issuable-form' into 'master'
GL dropdowns in issuable form ## What does this MR do? Changed all the issuable dropdown menus over to user GL dropdowns. This brings the dropdowns to be inline with the issuable filter dropdowns and allows for labels to be created whilst creating/editing an issuable. ## What are the relevant issue numbers? Closes #12574 ## Screenshots (if relevant) See merge request !4970
-rw-r--r--app/assets/javascripts/dispatcher.js.coffee2
-rw-r--r--app/assets/javascripts/labels_select.js.coffee31
-rw-r--r--app/assets/javascripts/milestone_select.js.coffee2
-rw-r--r--app/assets/javascripts/users_select.js.coffee9
-rw-r--r--app/assets/stylesheets/framework/dropdowns.scss2
-rw-r--r--app/assets/stylesheets/pages/merge_requests.scss4
-rw-r--r--app/helpers/issuables_helper.rb2
-rw-r--r--app/views/shared/issuable/_filter.html.haml4
-rw-r--r--app/views/shared/issuable/_form.html.haml36
-rw-r--r--app/views/shared/issuable/_label_dropdown.html.haml14
-rw-r--r--app/views/shared/issuable/_milestone_dropdown.html.haml8
-rw-r--r--features/project/issues/issues.feature1
-rw-r--r--features/steps/project/forked_merge_requests.rb12
-rw-r--r--features/steps/project/issues/issues.rb3
-rw-r--r--spec/features/issues/move_spec.rb2
-rw-r--r--spec/features/issues_spec.rb5
16 files changed, 72 insertions, 65 deletions
diff --git a/app/assets/javascripts/dispatcher.js.coffee b/app/assets/javascripts/dispatcher.js.coffee
index afaa6407b05..b5da15e9e49 100644
--- a/app/assets/javascripts/dispatcher.js.coffee
+++ b/app/assets/javascripts/dispatcher.js.coffee
@@ -39,6 +39,8 @@ class Dispatcher
shortcut_handler = new ShortcutsNavigation()
new GLForm($('.issue-form'))
new IssuableForm($('.issue-form'))
+ new LabelsSelect()
+ new MilestoneSelect()
when 'projects:merge_requests:new', 'projects:merge_requests:edit'
new Diff()
shortcut_handler = new ShortcutsNavigation()
diff --git a/app/assets/javascripts/labels_select.js.coffee b/app/assets/javascripts/labels_select.js.coffee
index 7688609b301..1a802b81452 100644
--- a/app/assets/javascripts/labels_select.js.coffee
+++ b/app/assets/javascripts/labels_select.js.coffee
@@ -184,20 +184,22 @@ class @LabelsSelect
.value()
if $dropdown.hasClass 'js-extra-options'
- if showNo
- data.unshift(
- id: 0
- title: 'No Label'
- )
-
+ extraData = []
if showAny
- data.unshift(
+ extraData.push(
isAny: true
title: 'Any Label'
)
- if data.length > 2
- data.splice 2, 0, 'divider'
+ if showNo
+ extraData.push(
+ id: 0
+ title: 'No Label'
+ )
+
+ if extraData.length
+ extraData.push 'divider'
+ data = extraData.concat(data)
callback data
@@ -287,6 +289,12 @@ class @LabelsSelect
defaultLabel
fieldName: $dropdown.data('field-name')
id: (label) ->
+ if $dropdown.hasClass('js-issuable-form-dropdown')
+ if label.id is 0
+ return
+ else
+ return label.id
+
if $dropdown.hasClass("js-filter-submit") and not label.isAny?
label.title
else
@@ -300,6 +308,9 @@ class @LabelsSelect
$selectbox.hide()
# display:block overrides the hide-collapse rule
$value.removeAttr('style')
+
+ return if $dropdown.hasClass('js-issuable-form-dropdown')
+
if $dropdown.hasClass 'js-multiselect'
if $dropdown.hasClass('js-filter-submit') and (isIssueIndex or isMRIndex)
selectedLabels = $dropdown
@@ -321,7 +332,7 @@ class @LabelsSelect
clicked: (label) ->
_this.enableBulkLabelDropdown()
- if $dropdown.hasClass('js-filter-bulk-update')
+ if $dropdown.hasClass('js-filter-bulk-update') or $dropdown.hasClass('js-issuable-form-dropdown')
return
page = $('body').data 'page'
diff --git a/app/assets/javascripts/milestone_select.js.coffee b/app/assets/javascripts/milestone_select.js.coffee
index 8ab03ed93ee..3a036569317 100644
--- a/app/assets/javascripts/milestone_select.js.coffee
+++ b/app/assets/javascripts/milestone_select.js.coffee
@@ -62,7 +62,7 @@ class @MilestoneSelect
title: 'Upcoming'
)
- if extraOptions.length > 2
+ if extraOptions.length > 0
extraOptions.push 'divider'
callback(extraOptions.concat(data))
diff --git a/app/assets/javascripts/users_select.js.coffee b/app/assets/javascripts/users_select.js.coffee
index 4e032ab1ff1..c84c4960657 100644
--- a/app/assets/javascripts/users_select.js.coffee
+++ b/app/assets/javascripts/users_select.js.coffee
@@ -151,11 +151,13 @@ class @UsersSelect
# display:block overrides the hide-collapse rule
$value.css('display', '')
- clicked: (user) ->
+ clicked: (user, $el, e) ->
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')
+ if $dropdown.hasClass('js-filter-bulk-update') or $dropdown.hasClass('js-issuable-form-dropdown')
+ e.preventDefault()
+ selectedId = user.id
return
if $dropdown.hasClass('js-filter-submit') and (isIssueIndex or isMRIndex)
@@ -168,7 +170,8 @@ class @UsersSelect
.closest('.selectbox')
.find("input[name='#{$dropdown.data('field-name')}']").val()
assignTo(selected)
-
+ id: (user) ->
+ user.id
renderRow: (user) ->
username = if user.username then "@#{user.username}" else ""
avatar = if user.avatar_url then user.avatar_url else false
diff --git a/app/assets/stylesheets/framework/dropdowns.scss b/app/assets/stylesheets/framework/dropdowns.scss
index d4e900f80ef..3fd0e12568d 100644
--- a/app/assets/stylesheets/framework/dropdowns.scss
+++ b/app/assets/stylesheets/framework/dropdowns.scss
@@ -56,7 +56,7 @@
position: absolute;
top: 50%;
right: 6px;
- margin-top: -4px;
+ margin-top: -6px;
color: $dropdown-toggle-icon-color;
font-size: 10px;
}
diff --git a/app/assets/stylesheets/pages/merge_requests.scss b/app/assets/stylesheets/pages/merge_requests.scss
index 15c6c9f231a..dba9a7ab3ee 100644
--- a/app/assets/stylesheets/pages/merge_requests.scss
+++ b/app/assets/stylesheets/pages/merge_requests.scss
@@ -324,6 +324,10 @@
.issuable-form-select-holder {
display: inline-block;
width: 250px;
+
+ .dropdown-menu-toggle {
+ width: 100%;
+ }
}
.table-holder {
diff --git a/app/helpers/issuables_helper.rb b/app/helpers/issuables_helper.rb
index 47d174361db..a3a8c7d5ff9 100644
--- a/app/helpers/issuables_helper.rb
+++ b/app/helpers/issuables_helper.rb
@@ -9,7 +9,7 @@ module IssuablesHelper
def multi_label_name(current_labels, default_label)
# current_labels may be a string from before
- if current_labels.is_a?(Array)
+ if current_labels.is_a?(Array) && current_labels.any?
if current_labels.count > 1
"#{current_labels[0]} +#{current_labels.count - 1} more"
else
diff --git a/app/views/shared/issuable/_filter.html.haml b/app/views/shared/issuable/_filter.html.haml
index 094d6636c66..d5199bd86dd 100644
--- a/app/views/shared/issuable/_filter.html.haml
+++ b/app/views/shared/issuable/_filter.html.haml
@@ -21,10 +21,10 @@
placeholder: "Search assignee", data: { any_user: "Any Assignee", first_user: (current_user.username if current_user), null_user: true, current_user: true, project_id: (@project.id if @project), selected: params[:assignee_id], field_name: "assignee_id", default_label: "Assignee" } })
.filter-item.inline.milestone-filter
- = render "shared/issuable/milestone_dropdown"
+ = render "shared/issuable/milestone_dropdown", selected: params[:milestone_title], name: :milestone_title, show_any: true, show_upcoming: true
.filter-item.inline.labels-filter
- = render "shared/issuable/label_dropdown"
+ = render "shared/issuable/label_dropdown", selected: params[:label_name], data_options: { field_name: "label_name[]" }
.pull-right
= render 'shared/sort_dropdown'
diff --git a/app/views/shared/issuable/_form.html.haml b/app/views/shared/issuable/_form.html.haml
index 98bbb12eaec..07b39c233b1 100644
--- a/app/views/shared/issuable/_form.html.haml
+++ b/app/views/shared/issuable/_form.html.haml
@@ -59,38 +59,24 @@
= f.label :assignee_id, "Assignee", class: "control-label #{"col-lg-4" if has_due_date}"
.col-sm-10{ class: ("col-lg-8" if has_due_date) }
.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)
- %div
- = link_to 'Assign to me', '#', class: 'assign-to-me-link prepend-top-5 inline'
+ - project = @target_project || @project
+ - if issuable.assignee_id
+ = hidden_field_tag("#{issuable.class.model_name.param_key}[assignee_id]", issuable.assignee_id)
+ = dropdown_tag(user_dropdown_label(issuable.assignee_id, "Assignee"), options: { toggle_class: "js-user-search js-issuable-form-dropdown js-assignee-search", title: "Filter by assignee", filter: true, dropdown_class: "dropdown-menu-user dropdown-menu-selectable dropdown-menu-assignee js-filter-submit",
+ placeholder: "Search assignee", data: { first_user: (current_user.username if current_user), null_user: true, current_user: true, project_id: (project.id if project), selected: issuable.assignee_id, field_name: "#{issuable.class.model_name.param_key}[assignee_id]", default_label: "Assignee" } })
.form-group.issue-milestone
= f.label :milestone_id, "Milestone", class: "control-label #{"col-lg-4" if has_due_date}"
.col-sm-10{ class: ("col-lg-8" if has_due_date) }
- - if milestone_options(issuable).present?
- .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.
- - if can? current_user, :admin_milestone, issuable.project
- %div
- = link_to 'Create new milestone', new_namespace_project_milestone_path(issuable.project.namespace, issuable.project), target: :blank, class: "prepend-top-5 inline"
+ .issuable-form-select-holder
+ = render "shared/issuable/milestone_dropdown", selected: issuable.milestone_id, name: "#{issuable.class.model_name.param_key}[milestone_id]", show_any: false, show_upcoming: false
.form-group
- has_labels = issuable.project.labels.any?
+ - selected_labels = issuable.label_ids.any? ? issuable.label_ids : nil
+ - label_dropdown_toggle = issuable.labels.map { |label| label.title }
= f.label :label_ids, "Labels", class: "control-label #{"col-lg-4" if has_due_date}"
.col-sm-10{ class: "#{"col-lg-8" if has_due_date} #{'issuable-form-padding-top' if !has_labels}" }
- - if has_labels
- .issuable-form-select-holder
- = f.collection_select :label_ids, issuable.project.labels.all, :id, :name,
- { selected: issuable.label_ids }, multiple: true, class: 'select2', data: { placeholder: "Select labels" }
- - else
- %span.light No labels yet.
- - if can? current_user, :admin_label, issuable.project
- %div
- = link_to 'Create new label', new_namespace_project_label_path(issuable.project.namespace, issuable.project), target: :blank, class: "prepend-top-5 inline"
+ .issuable-form-select-holder
+ = render "shared/issuable/label_dropdown", classes: ["js-issuable-form-dropdown"], selected: selected_labels, selected_toggle: label_dropdown_toggle, data_options: { field_name: "#{issuable.class.model_name.param_key}[label_ids][]", show_any: "false" }
- if has_due_date
.col-lg-6
.form-group
diff --git a/app/views/shared/issuable/_label_dropdown.html.haml b/app/views/shared/issuable/_label_dropdown.html.haml
index d34d28f6736..bcbe133ce62 100644
--- a/app/views/shared/issuable/_label_dropdown.html.haml
+++ b/app/views/shared/issuable/_label_dropdown.html.haml
@@ -4,19 +4,21 @@
- show_footer = local_assigns.fetch(:show_footer, true)
- data_options = local_assigns.fetch(:data_options, {})
- classes = local_assigns.fetch(:classes, [])
-- dropdown_data = {toggle: 'dropdown', field_name: 'label_name[]', show_no: "true", show_any: "true", selected: params[:label_name], project_id: @project.try(:id), labels: labels_filter_path, default_label: "Label"}
+- selected = local_assigns.fetch(:selected, nil)
+- selected_toggle = local_assigns.fetch(:selected_toggle, nil)
+- dropdown_data = {toggle: 'dropdown', field_name: "label_name[]", show_no: "true", show_any: "true", selected: selected, project_id: @project.try(:id), labels: labels_filter_path, default_label: "Label"}
- dropdown_data.merge!(data_options)
- classes << 'js-extra-options' if extra_options
- classes << 'js-filter-submit' if filter_submit
-- if params[:label_name].present?
- - if params[:label_name].respond_to?('any?')
- - params[:label_name].each do |label|
- = hidden_field_tag "label_name[]", label, id: nil
+- if selected.present?
+ - if selected.respond_to?('any?')
+ - selected.each do |label|
+ = hidden_field_tag data_options[:field_name], label, id: nil
.dropdown
%button.dropdown-menu-toggle.js-label-select.js-multiselect{class: classes.join(' '), type: "button", data: dropdown_data}
%span.dropdown-toggle-text
- = h(multi_label_name(params[:label_name], "Label"))
+ = h(multi_label_name(selected_toggle || selected, "Label"))
= icon('chevron-down')
.dropdown-menu.dropdown-select.dropdown-menu-paging.dropdown-menu-labels.dropdown-menu-selectable
= render partial: "shared/issuable/label_page_default", locals: { title: "Filter by label", show_footer: show_footer, show_create: show_create }
diff --git a/app/views/shared/issuable/_milestone_dropdown.html.haml b/app/views/shared/issuable/_milestone_dropdown.html.haml
index 2fcf40ece99..9188ef72d52 100644
--- a/app/views/shared/issuable/_milestone_dropdown.html.haml
+++ b/app/views/shared/issuable/_milestone_dropdown.html.haml
@@ -1,7 +1,7 @@
-- if params[:milestone_title].present?
- = hidden_field_tag(:milestone_title, params[:milestone_title])
-= dropdown_tag(milestone_dropdown_label(params[:milestone_title]), options: { title: "Filter by milestone", toggle_class: 'js-milestone-select js-filter-submit', filter: true, dropdown_class: "dropdown-menu-selectable",
- placeholder: "Search milestones", footer_content: @project.present?, data: { show_no: true, show_any: true, show_upcoming: true, field_name: "milestone_title", selected: params[:milestone_title], project_id: @project.try(:id), milestones: milestones_filter_dropdown_path, default_label: "Milestone" } }) do
+- if selected.present?
+ = hidden_field_tag(name, selected)
+= dropdown_tag(milestone_dropdown_label(selected), options: { title: "Filter by milestone", toggle_class: 'js-milestone-select js-filter-submit', filter: true, dropdown_class: "dropdown-menu-selectable",
+ placeholder: "Search milestones", footer_content: @project.present?, data: { show_no: true, show_any: show_any, show_upcoming: show_upcoming, field_name: name, selected: selected, project_id: @project.try(:id), milestones: milestones_filter_dropdown_path, default_label: "Milestone" } }) do
- if @project
%ul.dropdown-footer-list
- if can? current_user, :admin_milestone, @project
diff --git a/features/project/issues/issues.feature b/features/project/issues/issues.feature
index 358e622b736..80670063ea0 100644
--- a/features/project/issues/issues.feature
+++ b/features/project/issues/issues.feature
@@ -37,6 +37,7 @@ Feature: Project Issues
And I submit new issue "500 error on profile"
Then I should see issue "500 error on profile"
+ @javascript
Scenario: I submit new unassigned issue with labels
Given project "Shop" has labels: "bug", "feature", "enhancement"
And I click link "New Issue"
diff --git a/features/steps/project/forked_merge_requests.rb b/features/steps/project/forked_merge_requests.rb
index 6b56a77b832..8f71dfdd899 100644
--- a/features/steps/project/forked_merge_requests.rb
+++ b/features/steps/project/forked_merge_requests.rb
@@ -135,19 +135,17 @@ class Spinach::Features::ProjectForkedMergeRequests < Spinach::FeatureSteps
end
step 'I click "Assign to" dropdown"' do
- first('.ajax-users-select').click
+ click_button 'Assignee'
end
step 'I should see the target project ID in the input selector' do
- expect(page).to have_selector("input[data-project-id=\"#{@project.id}\"]")
+ expect(find('.js-assignee-search')["data-project-id"]).to eq "#{@project.id}"
end
step 'I should see the users from the target project ID' do
- expect(page).to have_selector('.user-result', visible: true, count: 3)
- users = page.all('.user-name')
- expect(users[0].text).to eq 'Unassigned'
- expect(users[1].text).to eq current_user.name
- expect(users[2].text).to eq @project.users.first.name
+ expect(page).to have_content 'Unassigned'
+ expect(page).to have_content current_user.name
+ expect(page).to have_content @project.users.first.name
end
# Verify a link is generated against the correct project
diff --git a/features/steps/project/issues/issues.rb b/features/steps/project/issues/issues.rb
index 35f166c7c08..b785e15f70e 100644
--- a/features/steps/project/issues/issues.rb
+++ b/features/steps/project/issues/issues.rb
@@ -82,7 +82,8 @@ class Spinach::Features::ProjectIssues < Spinach::FeatureSteps
step 'I submit new issue "500 error on profile" with label \'bug\'' do
fill_in "issue_title", with: "500 error on profile"
- select 'bug', from: "Labels"
+ click_button "Label"
+ click_link "bug"
click_button "Submit issue"
end
diff --git a/spec/features/issues/move_spec.rb b/spec/features/issues/move_spec.rb
index 7773c486b4e..055210399a7 100644
--- a/spec/features/issues/move_spec.rb
+++ b/spec/features/issues/move_spec.rb
@@ -55,7 +55,7 @@ feature 'issue move to another project' do
first('.select2-choice').click
end
- fill_in('s2id_autogen2_search', with: new_project_search.name)
+ fill_in('s2id_autogen1_search', with: new_project_search.name)
page.within '.select2-drop' do
expect(page).to have_content(new_project_search.name)
diff --git a/spec/features/issues_spec.rb b/spec/features/issues_spec.rb
index cfe6349a1a1..3fec75a07df 100644
--- a/spec/features/issues_spec.rb
+++ b/spec/features/issues_spec.rb
@@ -50,9 +50,8 @@ describe 'Issues', feature: true do
expect(page).to have_content "Assignee #{@user.name}"
- first('#s2id_issue_assignee_id').click
- sleep 2 # wait for ajax stuff to complete
- first('.user-result').click
+ first('.js-user-search').click
+ click_link 'Unassigned'
click_button 'Save changes'