Commit 766f9cf2 authored by tiagonbotelho's avatar tiagonbotelho

implements the basic filter functionality

parent 81e57e78
......@@ -8,6 +8,7 @@ v 8.10.0 (unreleased)
- Add the functionality to be able to rename a file. !5049 (tiagonbotelho)
- Disable PostgreSQL statement timeout during migrations
- Fix projects dropdown loading performance with a simplified api cal. !5113 (tiagonbotelho)
- User can now filter branches by name on /branches page. !5144 (tiagonbotelho)
- Fix commit builds API, return all builds for all pipelines for given commit. !4849
- Replace Haml with Hamlit to make view rendering faster. !3666
- Refresh the branch cache after `git gc` runs
......
......@@ -6,8 +6,7 @@ class Projects::BranchesController < Projects::ApplicationController
before_action :authorize_push_code!, only: [:new, :create, :destroy]
def index
@sort = params[:sort] || 'name'
@branches = @repository.branches_sorted_by(@sort)
@branches = BranchesFinder.new(@repository, params).execute
@branches = Kaminari.paginate_array(@branches).page(params[:page])
@max_commits = @branches.reduce(0) do |memo, branch|
......
class BranchesFinder
def initialize(repository, params)
@repository = repository
@params = params
end
def execute
branches = @repository.branches_sorted_by(sort)
filter_by_name(branches)
end
private
attr_reader :repository, :params
def search
@params[:search].presence
end
def sort
@params[:sort].presence || 'name'
end
def filter_by_name(branches)
if search
branches.select { |branch| branch.name.include?(search) }
else
branches
end
end
end
......@@ -9,6 +9,17 @@ module BranchesHelper
end
end
def filter_branches_path(options = {})
exist_opts = {
search: params[:search],
sort: params[:sort]
}
options = exist_opts.merge(options)
namespace_project_branches_path(@project.namespace, @project, @id, options)
end
def can_push_branch?(project, branch_name)
return false unless project.repository.branch_exists?(branch_name)
......
......@@ -125,6 +125,11 @@ class Repository
commits
end
def find_similar_branches(search)
raw_repository.branches.select { |branch| branch.name.include?(search) }
end
def find_branch(name)
raw_repository.branches.find { |branch| branch.name == name }
end
......@@ -606,6 +611,8 @@ class Repository
# Remove archives older than 2 hours
def branches_sorted_by(value)
case value
when 'name'
branches.sort_by(&:name)
when 'recently_updated'
branches.sort do |a, b|
commit(b.target).committed_date <=> commit(a.target).committed_date
......
......@@ -9,26 +9,31 @@
- if can? current_user, :push_code, @project
.nav-controls
= link_to new_namespace_project_branch_path(@project.namespace, @project), class: 'btn btn-create' do
New branch
= form_tag(filter_branches_path, method: :get) do
= search_field_tag :search, params[:search], { placeholder: 'Filter by branch name', id: 'branch-search', class: 'form-control search-text-input input-short', spellcheck: false }
.dropdown.inline
%button.dropdown-toggle.btn{type: 'button', 'data-toggle' => 'dropdown'}
%span.light
- if @sort.present?
= @sort.humanize
- if params[:sort].present?
= params[:sort].humanize
- else
Name
%b.caret
%ul.dropdown-menu.dropdown-menu-align-right
%li
= link_to namespace_project_branches_path(sort: nil) do
Name
= link_to namespace_project_branches_path(sort: 'recently_updated') do
= link_to filter_branches_path(sort: nil) do
= sort_title_name
= link_to filter_branches_path(sort: 'recently_updated') do
= sort_title_recently_updated
= link_to namespace_project_branches_path(sort: 'last_updated') do
= link_to filter_branches_path(sort: 'last_updated') do
= sort_title_oldest_updated
= link_to new_namespace_project_branch_path(@project.namespace, @project), class: 'btn btn-create' do
New branch
- if @branches.any?
%ul.content-list.all-branches
- @branches.each do |branch|
= render "projects/branches/branch", branch: branch
= paginate @branches, theme: 'gitlab'
- else
.nothing-here-block No branches to show
......@@ -84,10 +84,10 @@ ActiveRecord::Schema.define(version: 20160716115710) do
t.string "health_check_access_token"
t.boolean "send_user_confirmation_email", default: false
t.integer "container_registry_token_expire_delay", default: 5
t.boolean "user_default_external", default: false, null: false
t.text "after_sign_up_text"
t.string "repository_storage", default: "default"
t.string "enabled_git_access_protocol"
t.boolean "user_default_external", default: false, null: false
end
create_table "audit_events", force: :cascade do |t|
......
require 'spec_helper'
describe 'Branches', feature: true do
let(:project) { create(:project) }
let(:repository) { project.repository }
before do
login_as :user
project.team << [@user, :developer]
end
describe 'Initial branches page' do
it 'shows all the branches' do
visit namespace_project_branches_path(project.namespace, project)
repository.branches { |branch| expect(page).to have_content("#{branch.name}") }
expect(page).to have_content("Protected branches can be managed in project settings")
end
end
describe 'Find branches' do
it 'shows filtered branches', js: true do
visit namespace_project_branches_path(project.namespace, project, project.id)
fill_in 'branch-search', with: 'fix'
find('#branch-search').native.send_keys(:enter)
expect(page).to have_content('fix')
expect(find('.all-branches')).to have_selector('li', count: 1)
end
end
end
require 'spec_helper'
describe BranchesFinder do
let(:user) { create(:user) }
let(:project) { create(:project) }
let(:repository) { project.repository }
describe '#execute' do
context 'sort only' do
it 'sorts by name' do
branches_finder = described_class.new(repository, {})
result = branches_finder.execute
expect(result.first.name).to eq("'test'")
end
it 'sorts by recently_updated' do
branches_finder = described_class.new(repository, { sort: 'recently_updated' })
result = branches_finder.execute
expect(result.first.name).to eq('expand-collapse-lines')
end
it 'sorts by last_updated' do
branches_finder = described_class.new(repository, { sort: 'last_updated' })
result = branches_finder.execute
expect(result.first.name).to eq('feature')
end
end
context 'filter only' do
it 'filters branches by name' do
branches_finder = described_class.new(repository, { search: 'fix' })
result = branches_finder.execute
expect(result.first.name).to eq('fix')
expect(result.count).to eq(1)
end
it 'does not find any branch with that name' do
branches_finder = described_class.new(repository, { search: 'random' })
result = branches_finder.execute
expect(result.count).to eq(0)
end
end
context 'filter and sort' do
it 'filters branches by name and sorts by recently_updated' do
params = { sort: 'recently_updated', search: 'feature' }
branches_finder = described_class.new(repository, params)
result = branches_finder.execute
expect(result.first.name).to eq('feature_conflict')
expect(result.count).to eq(2)
end
it 'filters branches by name and sorts by last_updated' do
params = { sort: 'last_updated', search: 'feature' }
branches_finder = described_class.new(repository, params)
result = branches_finder.execute
expect(result.first.name).to eq('feature')
expect(result.count).to eq(2)
end
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment