Merge branch 'async-refs-dropdown' into 'master'
Refs dropdown is now loaded async ## What does this MR do? The refs dropdown is loaded async so not to block the page. ## What are the relevant issue numbers? Part of #18202 ## Screenshots (if relevant) ![Screen_Shot_2016-06-07_at_14.41.21](/uploads/8fea12655f96fe7f7008a32677bff037/Screen_Shot_2016-06-07_at_14.41.21.png) See merge request !4508
This commit is contained in:
commit
d5bbc86094
15 changed files with 133 additions and 86 deletions
|
@ -58,7 +58,7 @@ class GitLabDropdownFilter
|
|||
filter: (search_text) ->
|
||||
data = @options.data()
|
||||
|
||||
if data?
|
||||
if data? and not @options.filterByText
|
||||
results = data
|
||||
|
||||
if search_text isnt ''
|
||||
|
@ -102,10 +102,11 @@ class GitLabDropdownFilter
|
|||
$el = $(@)
|
||||
matches = fuzzaldrinPlus.match($el.text().trim(), search_text)
|
||||
|
||||
if matches.length
|
||||
$el.show()
|
||||
else
|
||||
$el.hide()
|
||||
unless $el.is('.dropdown-header')
|
||||
if matches.length
|
||||
$el.show()
|
||||
else
|
||||
$el.hide()
|
||||
else
|
||||
elements.show()
|
||||
|
||||
|
@ -191,6 +192,7 @@ class GitLabDropdown
|
|||
if @options.filterable
|
||||
@filter = new GitLabDropdownFilter @filterInput,
|
||||
filterInputBlur: @filterInputBlur
|
||||
filterByText: @options.filterByText
|
||||
remote: @options.filterRemote
|
||||
query: @options.data
|
||||
keys: searchFields
|
||||
|
|
|
@ -19,6 +19,7 @@ class @Project
|
|||
$('.clone').text(url)
|
||||
|
||||
# Ref switcher
|
||||
@initRefSwitcher()
|
||||
$('.project-refs-select').on 'change', ->
|
||||
$(@).parents('form').submit()
|
||||
|
||||
|
@ -50,3 +51,39 @@ class @Project
|
|||
|
||||
changeProject: (url) ->
|
||||
window.location = url
|
||||
|
||||
initRefSwitcher: ->
|
||||
$('.js-project-refs-dropdown').each ->
|
||||
$dropdown = $(@)
|
||||
selected = $dropdown.data('selected')
|
||||
|
||||
$dropdown.glDropdown(
|
||||
data: (term, callback) ->
|
||||
$.ajax(
|
||||
url: $dropdown.data('refs-url')
|
||||
data:
|
||||
ref: $dropdown.data('ref')
|
||||
).done (refs) ->
|
||||
callback(refs)
|
||||
selectable: true
|
||||
filterable: true
|
||||
filterByText: true
|
||||
fieldName: 'ref'
|
||||
renderRow: (ref) ->
|
||||
if ref.header?
|
||||
"<li class='dropdown-header'>#{ref.header}</li>"
|
||||
else
|
||||
isActiveClass = if ref is selected then 'is-active' else ''
|
||||
|
||||
"<li>
|
||||
<a href='#' data-ref='#{escape(ref)}' class='#{isActiveClass}'>
|
||||
#{ref}
|
||||
</a>
|
||||
</li>"
|
||||
id: (obj, $el) ->
|
||||
$el.data('ref')
|
||||
toggleLabel: (obj, $el) ->
|
||||
$el.text().trim()
|
||||
clicked: (e) ->
|
||||
$dropdown.closest('form').submit()
|
||||
)
|
||||
|
|
|
@ -9,6 +9,10 @@
|
|||
margin-top: -2px;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.dropdown-menu-toggle {
|
||||
line-height: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.panel-body {
|
||||
|
|
|
@ -165,11 +165,6 @@
|
|||
background-size: 16px 16px !important;
|
||||
}
|
||||
|
||||
/** Branch/tag selector **/
|
||||
.project-refs-form .select2-container {
|
||||
width: 160px !important;
|
||||
}
|
||||
|
||||
.select2-results .select2-no-results,
|
||||
.select2-results .select2-searching,
|
||||
.select2-results .select2-ajax-error,
|
||||
|
|
|
@ -616,3 +616,9 @@ pre.light-well {
|
|||
color: $gl-text-green;
|
||||
}
|
||||
}
|
||||
|
||||
.project-refs-form {
|
||||
.dropdown-menu {
|
||||
width: 300px;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
class ProjectsController < Projects::ApplicationController
|
||||
include ExtractsPath
|
||||
|
||||
before_action :authenticate_user!, except: [:show, :activity]
|
||||
before_action :authenticate_user!, except: [:show, :activity, :refs]
|
||||
before_action :project, except: [:new, :create]
|
||||
before_action :repository, except: [:new, :create]
|
||||
before_action :assign_ref_vars, :tree, only: [:show], if: :repo_exists?
|
||||
|
@ -251,6 +251,24 @@ class ProjectsController < Projects::ApplicationController
|
|||
}
|
||||
end
|
||||
|
||||
def refs
|
||||
options = {
|
||||
'Branches' => @repository.branch_names,
|
||||
}
|
||||
|
||||
unless @repository.tag_count.zero?
|
||||
options['Tags'] = VersionSorter.rsort(@repository.tag_names)
|
||||
end
|
||||
|
||||
# If reference is commit id - we should add it to branch/tag selectbox
|
||||
ref = Addressable::URI.unescape(params[:ref])
|
||||
if ref && options.flatten(2).exclude?(ref) && ref =~ /\A[0-9a-zA-Z]{6,52}\z/
|
||||
options['Commits'] = [ref]
|
||||
end
|
||||
|
||||
render json: options.to_json
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def determine_layout
|
||||
|
|
|
@ -101,22 +101,6 @@ module ApplicationHelper
|
|||
'Never'
|
||||
end
|
||||
|
||||
def grouped_options_refs
|
||||
repository = @project.repository
|
||||
|
||||
options = [
|
||||
['Branches', repository.branch_names],
|
||||
['Tags', VersionSorter.rsort(repository.tag_names)]
|
||||
]
|
||||
|
||||
# If reference is commit id - we should add it to branch/tag selectbox
|
||||
if @ref && !options.flatten.include?(@ref) && @ref =~ /\A[0-9a-zA-Z]{6,52}\z/
|
||||
options << ['Commit', [@ref]]
|
||||
end
|
||||
|
||||
grouped_options_for_select(options, @ref || @project.default_branch)
|
||||
end
|
||||
|
||||
# Define whenever show last push event
|
||||
# with suggestion to create MR
|
||||
def show_last_push_widget?(event)
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
%b Builds badge ·
|
||||
= @build_badge.to_html
|
||||
.pull-right
|
||||
= render 'shared/ref_switcher', destination: 'badges'
|
||||
= render 'shared/ref_switcher', destination: 'badges', align_right: true
|
||||
.panel-body
|
||||
.row
|
||||
.col-md-2.text-center
|
||||
|
|
|
@ -1,7 +1,14 @@
|
|||
- dropdown_toggle_text = @ref || @project.default_branch
|
||||
= form_tag switch_namespace_project_refs_path(@project.namespace, @project), method: :get, class: "project-refs-form" do
|
||||
= select_tag "ref", grouped_options_refs, class: "project-refs-select select2 select2-sm"
|
||||
= hidden_field_tag :destination, destination
|
||||
- if defined?(path)
|
||||
= hidden_field_tag :path, path
|
||||
- @options && @options.each do |key, value|
|
||||
= hidden_field_tag key, value, id: nil
|
||||
.dropdown
|
||||
= dropdown_toggle dropdown_toggle_text, { toggle: "dropdown", selected: dropdown_toggle_text, ref: @ref, refs_url: refs_namespace_project_path(@project.namespace, @project) }, { toggle_class: "js-project-refs-dropdown" }
|
||||
.dropdown-menu.dropdown-menu-selectable{ class: ("dropdown-menu-align-right" if local_assigns[:align_right]) }
|
||||
= dropdown_title "Switch branch/tag"
|
||||
= dropdown_filter "Search branches and tags"
|
||||
= dropdown_content
|
||||
= dropdown_loading
|
||||
|
|
|
@ -479,6 +479,7 @@ Rails.application.routes.draw do
|
|||
get :download_export
|
||||
get :autocomplete_sources
|
||||
get :activity
|
||||
get :refs
|
||||
end
|
||||
|
||||
scope module: :projects do
|
||||
|
|
|
@ -20,11 +20,11 @@ class Spinach::Features::ProjectNetworkGraph < Spinach::FeatureSteps
|
|||
end
|
||||
|
||||
step 'page should select "master" in select box' do
|
||||
expect(page).to have_selector '.select2-chosen', text: "master"
|
||||
expect(page).to have_selector '.dropdown-menu-toggle', text: "master"
|
||||
end
|
||||
|
||||
step 'page should select "v1.0.0" in select box' do
|
||||
expect(page).to have_selector '.select2-chosen', text: "v1.0.0"
|
||||
expect(page).to have_selector '.dropdown-menu-toggle', text: "v1.0.0"
|
||||
end
|
||||
|
||||
step 'page should have "master" on graph' do
|
||||
|
@ -40,11 +40,19 @@ class Spinach::Features::ProjectNetworkGraph < Spinach::FeatureSteps
|
|||
end
|
||||
|
||||
When 'I switch ref to "feature"' do
|
||||
select 'feature', from: 'ref'
|
||||
first('.js-project-refs-dropdown').click
|
||||
|
||||
page.within '.project-refs-form' do
|
||||
click_link 'feature'
|
||||
end
|
||||
end
|
||||
|
||||
When 'I switch ref to "v1.0.0"' do
|
||||
select 'v1.0.0', from: 'ref'
|
||||
first('.js-project-refs-dropdown').click
|
||||
|
||||
page.within '.project-refs-form' do
|
||||
click_link 'v1.0.0'
|
||||
end
|
||||
end
|
||||
|
||||
When 'click "Show only selected branch" checkbox' do
|
||||
|
@ -68,11 +76,11 @@ class Spinach::Features::ProjectNetworkGraph < Spinach::FeatureSteps
|
|||
end
|
||||
|
||||
step 'page should select "feature" in select box' do
|
||||
expect(page).to have_selector '.select2-chosen', text: "feature"
|
||||
expect(page).to have_selector '.dropdown-menu-toggle', text: "feature"
|
||||
end
|
||||
|
||||
step 'page should select "v1.0.0" in select box' do
|
||||
expect(page).to have_selector '.select2-chosen', text: "v1.0.0"
|
||||
expect(page).to have_selector '.dropdown-menu-toggle', text: "v1.0.0"
|
||||
end
|
||||
|
||||
step 'page should have "feature" on graph' do
|
||||
|
|
|
@ -290,15 +290,23 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps
|
|||
end
|
||||
|
||||
step "I switch ref to 'test'" do
|
||||
select "'test'", from: 'ref'
|
||||
first('.js-project-refs-dropdown').click
|
||||
|
||||
page.within '.project-refs-form' do
|
||||
click_link 'test'
|
||||
end
|
||||
end
|
||||
|
||||
step "I switch ref to fix" do
|
||||
select "fix", from: 'ref'
|
||||
first('.js-project-refs-dropdown').click
|
||||
|
||||
page.within '.project-refs-form' do
|
||||
click_link 'fix'
|
||||
end
|
||||
end
|
||||
|
||||
step "I see the ref 'test' has been selected" do
|
||||
expect(page).to have_selector '.select2-chosen', text: "'test'"
|
||||
expect(page).to have_selector '.dropdown-toggle-text', text: "'test'"
|
||||
end
|
||||
|
||||
step "I visit the 'test' tree" do
|
||||
|
|
|
@ -237,4 +237,24 @@ describe ProjectsController do
|
|||
expect(response.status).to eq(401)
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET refs" do
|
||||
it "should get a list of branches and tags" do
|
||||
get :refs, namespace_id: public_project.namespace.path, id: public_project.path
|
||||
|
||||
parsed_body = JSON.parse(response.body)
|
||||
expect(parsed_body["Branches"]).to include("master")
|
||||
expect(parsed_body["Tags"]).to include("v1.0.0")
|
||||
expect(parsed_body["Commits"]).to be_nil
|
||||
end
|
||||
|
||||
it "should get a list of branches, tags and commits" do
|
||||
get :refs, namespace_id: public_project.namespace.path, id: public_project.path, ref: "123456"
|
||||
|
||||
parsed_body = JSON.parse(response.body)
|
||||
expect(parsed_body["Branches"]).to include("master")
|
||||
expect(parsed_body["Tags"]).to include("v1.0.0")
|
||||
expect(parsed_body["Commits"]).to include("123456")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
require 'spec_helper'
|
||||
|
||||
feature 'list of badges' do
|
||||
include Select2Helper
|
||||
|
||||
background do
|
||||
user = create(:user)
|
||||
project = create(:project)
|
||||
|
@ -24,7 +22,11 @@ feature 'list of badges' do
|
|||
end
|
||||
|
||||
scenario 'user changes current ref on badges list page', js: true do
|
||||
select2('improve/awesome', from: '#ref')
|
||||
first('.js-project-refs-dropdown').click
|
||||
|
||||
page.within '.project-refs-form' do
|
||||
click_link 'improve/awesome'
|
||||
end
|
||||
|
||||
expect(page).to have_content 'badges/improve/awesome/build.svg'
|
||||
end
|
||||
|
|
|
@ -174,51 +174,6 @@ describe ApplicationHelper do
|
|||
end
|
||||
end
|
||||
|
||||
describe 'grouped_options_refs' do
|
||||
let(:options) { helper.grouped_options_refs }
|
||||
let(:project) { create(:project) }
|
||||
|
||||
before do
|
||||
assign(:project, project)
|
||||
|
||||
# Override Rails' grouped_options_for_select helper to just return the
|
||||
# first argument (`options`), since it's easier to work with than the
|
||||
# generated HTML.
|
||||
allow(helper).to receive(:grouped_options_for_select).
|
||||
and_wrap_original { |_, *args| args.first }
|
||||
end
|
||||
|
||||
it 'includes a list of branch names' do
|
||||
expect(options[0][0]).to eq('Branches')
|
||||
expect(options[0][1]).to include('master', 'feature')
|
||||
end
|
||||
|
||||
it 'includes a list of tag names' do
|
||||
expect(options[1][0]).to eq('Tags')
|
||||
expect(options[1][1]).to include('v1.0.0', 'v1.1.0')
|
||||
end
|
||||
|
||||
it 'includes a specific commit ref if defined' do
|
||||
# Must be an instance variable
|
||||
ref = '2ed06dc41dbb5936af845b87d79e05bbf24c73b8'
|
||||
assign(:ref, ref)
|
||||
|
||||
expect(options[2][0]).to eq('Commit')
|
||||
expect(options[2][1]).to eq([ref])
|
||||
end
|
||||
|
||||
it 'sorts tags in a natural order' do
|
||||
# Stub repository.tag_names to make sure we get some valid testing data
|
||||
expect(project.repository).to receive(:tag_names).
|
||||
and_return(['v1.0.9', 'v1.0.10', 'v2.0', 'v3.1.4.2', 'v2.0rc1¿',
|
||||
'v1.0.9a', 'v2.0-rc1', 'v2.0rc2'])
|
||||
|
||||
expect(options[1][1]).
|
||||
to eq(['v3.1.4.2', 'v2.0', 'v2.0rc2', 'v2.0rc1¿', 'v2.0-rc1', 'v1.0.10',
|
||||
'v1.0.9', 'v1.0.9a'])
|
||||
end
|
||||
end
|
||||
|
||||
describe 'simple_sanitize' do
|
||||
let(:a_tag) { '<a href="#">Foo</a>' }
|
||||
|
||||
|
|
Loading…
Reference in a new issue