diff options
-rw-r--r-- | app/assets/javascripts/dispatcher.js | 2 | ||||
-rw-r--r-- | app/assets/javascripts/issuable/auto_width_dropdown_select.js | 38 | ||||
-rw-r--r-- | app/assets/javascripts/new_branch_form.js | 16 | ||||
-rw-r--r-- | app/assets/stylesheets/pages/merge_requests.scss | 4 | ||||
-rw-r--r-- | app/views/projects/branches/new.html.haml | 12 | ||||
-rw-r--r-- | app/views/projects/compare/_form.html.haml | 4 | ||||
-rw-r--r-- | app/views/shared/_ref_dropdown.html.haml (renamed from app/views/projects/compare/_ref_dropdown.html.haml) | 4 | ||||
-rw-r--r-- | app/views/shared/issuable/form/_branch_chooser.html.haml | 10 | ||||
-rw-r--r-- | spec/features/projects/branches/new_branch_ref_dropdown_spec.rb | 48 |
9 files changed, 126 insertions, 12 deletions
diff --git a/app/assets/javascripts/dispatcher.js b/app/assets/javascripts/dispatcher.js index 7e469153106..b87c57c38fe 100644 --- a/app/assets/javascripts/dispatcher.js +++ b/app/assets/javascripts/dispatcher.js @@ -50,6 +50,7 @@ import UserCallout from './user_callout'; import { ProtectedTagCreate, ProtectedTagEditList } from './protected_tags'; import ShortcutsWiki from './shortcuts_wiki'; import BlobViewer from './blob/viewer/index'; +import AutoWidthDropdownSelect from './issuable/auto_width_dropdown_select'; const ShortcutsBlob = require('./shortcuts_blob'); @@ -198,6 +199,7 @@ const ShortcutsBlob = require('./shortcuts_blob'); new LabelsSelect(); new MilestoneSelect(); new gl.IssuableTemplateSelectors(); + new AutoWidthDropdownSelect($('.js-target-branch-select')).init(); break; case 'projects:tags:new': new ZenMode(); diff --git a/app/assets/javascripts/issuable/auto_width_dropdown_select.js b/app/assets/javascripts/issuable/auto_width_dropdown_select.js new file mode 100644 index 00000000000..2203a56315e --- /dev/null +++ b/app/assets/javascripts/issuable/auto_width_dropdown_select.js @@ -0,0 +1,38 @@ +let instanceCount = 0; + +class AutoWidthDropdownSelect { + constructor(selectElement) { + this.$selectElement = $(selectElement); + this.dropdownClass = `js-auto-width-select-dropdown-${instanceCount}`; + instanceCount += 1; + } + + init() { + const dropdownClass = this.dropdownClass; + this.$selectElement.select2({ + dropdownCssClass: dropdownClass, + dropdownCss() { + let resultantWidth = 'auto'; + const $dropdown = $(`.${dropdownClass}`); + + // We have to look at the parent because + // `offsetParent` on a `display: none;` is `null` + const offsetParentWidth = $(this).parent().offsetParent().width(); + // Reset any width to let it naturally flow + $dropdown.css('width', 'auto'); + if ($dropdown.outerWidth(false) > offsetParentWidth) { + resultantWidth = offsetParentWidth; + } + + return { + width: resultantWidth, + maxWidth: offsetParentWidth, + }; + }, + }); + + return this; + } +} + +export default AutoWidthDropdownSelect; diff --git a/app/assets/javascripts/new_branch_form.js b/app/assets/javascripts/new_branch_form.js index 5828f460a23..67046d52a65 100644 --- a/app/assets/javascripts/new_branch_form.js +++ b/app/assets/javascripts/new_branch_form.js @@ -34,6 +34,7 @@ filterByText: true, remote: false, fieldName: $branchSelect.data('field-name'), + filterInput: 'input[type="search"]', selectable: true, isSelectable: function(branch, $el) { return !$el.hasClass('is-active'); @@ -50,6 +51,21 @@ } } }); + + const $dropdownContainer = $branchSelect.closest('.dropdown'); + const $fieldInput = $(`input[name="${$branchSelect.data('field-name')}"]`, $dropdownContainer); + const $filterInput = $('input[type="search"]', $dropdownContainer); + + $filterInput.on('keyup', (e) => { + const keyCode = e.keyCode || e.which; + if (keyCode !== 13) return; + + const text = $filterInput.val(); + $fieldInput.val(text); + $('.dropdown-toggle-text', $branchSelect).text(text); + + $dropdownContainer.removeClass('open'); + }); }; NewBranchForm.prototype.setupRestrictions = function() { diff --git a/app/assets/stylesheets/pages/merge_requests.scss b/app/assets/stylesheets/pages/merge_requests.scss index bca62b7fc31..72660113e3c 100644 --- a/app/assets/stylesheets/pages/merge_requests.scss +++ b/app/assets/stylesheets/pages/merge_requests.scss @@ -482,6 +482,10 @@ } } +.target-branch-select-dropdown-container { + position: relative; +} + .assign-to-me-link { padding-left: 12px; white-space: nowrap; diff --git a/app/views/projects/branches/new.html.haml b/app/views/projects/branches/new.html.haml index d3c3e40d518..796ecdfd014 100644 --- a/app/views/projects/branches/new.html.haml +++ b/app/views/projects/branches/new.html.haml @@ -1,4 +1,5 @@ - page_title "New Branch" +- default_ref = params[:ref] || @project.default_branch - if @error .alert.alert-danger @@ -16,12 +17,11 @@ .help-block.text-danger.js-branch-name-error .form-group = label_tag :ref, 'Create from', class: 'control-label' - .col-sm-10 - = hidden_field_tag :ref, params[:ref] || @project.default_branch - = dropdown_tag(params[:ref] || @project.default_branch, - options: { toggle_class: 'js-branch-select wide', - filter: true, dropdown_class: "dropdown-menu-selectable", placeholder: "Search branches", - data: { selected: params[:ref] || @project.default_branch, field_name: 'ref' } }) + .col-sm-10.dropdown.create-from + = hidden_field_tag :ref, default_ref + = button_tag type: 'button', title: default_ref, class: 'dropdown-toggle form-control js-branch-select', required: true, data: { toggle: 'dropdown', selected: default_ref, field_name: 'ref' } do + .text-left.dropdown-toggle-text= default_ref + = render 'shared/ref_dropdown', dropdown_class: 'wide' .help-block Existing branch name, tag, or commit SHA .form-actions = button_tag 'Create branch', class: 'btn btn-create', tabindex: 3 diff --git a/app/views/projects/compare/_form.html.haml b/app/views/projects/compare/_form.html.haml index 0f080b6acee..1f4c9fac54c 100644 --- a/app/views/projects/compare/_form.html.haml +++ b/app/views/projects/compare/_form.html.haml @@ -9,7 +9,7 @@ = hidden_field_tag :from, params[:from] = button_tag type: 'button', title: params[:from], class: "form-control compare-dropdown-toggle js-compare-dropdown has-tooltip", required: true, data: { refs_url: refs_namespace_project_path(@project.namespace, @project), toggle: "dropdown", target: ".js-compare-from-dropdown", selected: params[:from], field_name: :from } do .dropdown-toggle-text.str-truncated= params[:from] || 'Select branch/tag' - = render "ref_dropdown" + = render 'shared/ref_dropdown' .compare-ellipsis.inline ... .form-group.dropdown.compare-form-group.to.js-compare-to-dropdown .input-group.inline-input-group @@ -17,7 +17,7 @@ = hidden_field_tag :to, params[:to] = button_tag type: 'button', title: params[:to], class: "form-control compare-dropdown-toggle js-compare-dropdown has-tooltip", required: true, data: { refs_url: refs_namespace_project_path(@project.namespace, @project), toggle: "dropdown", target: ".js-compare-to-dropdown", selected: params[:to], field_name: :to } do .dropdown-toggle-text.str-truncated= params[:to] || 'Select branch/tag' - = render "ref_dropdown" + = render 'shared/ref_dropdown' = button_tag "Compare", class: "btn btn-create commits-compare-btn" - if @merge_request.present? diff --git a/app/views/projects/compare/_ref_dropdown.html.haml b/app/views/shared/_ref_dropdown.html.haml index 05fb37cdc0f..96f68c80c48 100644 --- a/app/views/projects/compare/_ref_dropdown.html.haml +++ b/app/views/shared/_ref_dropdown.html.haml @@ -1,4 +1,6 @@ -.dropdown-menu.dropdown-menu-selectable +- dropdown_class = local_assigns.fetch(:dropdown_class, '') + +.dropdown-menu.dropdown-menu-selectable{ class: dropdown_class } = dropdown_title "Select Git revision" = dropdown_filter "Filter by Git revision" = dropdown_content diff --git a/app/views/shared/issuable/form/_branch_chooser.html.haml b/app/views/shared/issuable/form/_branch_chooser.html.haml index 2793e7bcff4..f57b4d899ce 100644 --- a/app/views/shared/issuable/form/_branch_chooser.html.haml +++ b/app/views/shared/issuable/form/_branch_chooser.html.haml @@ -10,12 +10,16 @@ = form.label :source_branch, class: 'control-label' .col-sm-10 .issuable-form-select-holder - = form.select(:source_branch, [issuable.source_branch], {}, { class: 'source_branch select2 span2', disabled: true }) + = form.select(:source_branch, [issuable.source_branch], {}, { class: 'source_branch select2', disabled: true }) .form-group = form.label :target_branch, class: 'control-label' - .col-sm-10 + .col-sm-10.target-branch-select-dropdown-container .issuable-form-select-holder - = form.select(:target_branch, issuable.target_branches, { include_blank: true }, { class: 'target_branch select2 span2', disabled: issuable.new_record?, data: { placeholder: "Select branch" }}) + = form.select(:target_branch, issuable.target_branches, + { include_blank: true }, + { class: 'target_branch js-target-branch-select', + disabled: issuable.new_record?, + data: { placeholder: "Select branch" }}) - if issuable.new_record? = link_to 'Change branches', mr_change_branches_path(issuable) diff --git a/spec/features/projects/branches/new_branch_ref_dropdown_spec.rb b/spec/features/projects/branches/new_branch_ref_dropdown_spec.rb new file mode 100644 index 00000000000..cfc782c98ad --- /dev/null +++ b/spec/features/projects/branches/new_branch_ref_dropdown_spec.rb @@ -0,0 +1,48 @@ +require 'spec_helper' + +describe 'New Branch Ref Dropdown', :js, :feature do + let(:user) { create(:user) } + let(:project) { create(:project, :public) } + let(:toggle) { find('.create-from .dropdown-toggle') } + + before do + project.add_master(user) + + login_as(user) + visit new_namespace_project_branch_path(project.namespace, project) + end + + it 'filters a list of branches and tags' do + toggle.click + + filter_by('v1.0.0') + + expect(items_count).to be(1) + + filter_by('video') + + expect(items_count).to be(1) + + find('.create-from .dropdown-content li').click + + expect(toggle).to have_content 'video' + end + + it 'accepts a manually entered commit SHA' do + toggle.click + + filter_by('somecommitsha') + + find('.create-from input[type=search]').send_keys(:enter) + + expect(toggle).to have_content 'somecommitsha' + end + + def items_count + all('.create-from .dropdown-content li').length + end + + def filter_by(filter_text) + fill_in 'Filter by Git revision', with: filter_text + end +end |