[refs #90] autocomplete

This commit is contained in:
Alexander Machehin 2012-07-06 23:30:01 +06:00
parent 9e68dae63b
commit dd221cc880
6 changed files with 78 additions and 53 deletions

View File

@ -1,23 +1,26 @@
# -*- encoding : utf-8 -*-
class Projects::PullRequestsController < Projects::BaseController
SKIP = [:autocomplete_base_project_name, :autocomplete_head_project_name, :autocomplete_base_ref, :autocomplete_head_ref]
before_filter :authenticate_user!
skip_before_filter :authenticate_user!, :only => [:index, :show] if APP_CONFIG['anonymous_access']
load_resource :project
load_and_authorize_resource :issue, :through => :project, :find_by => :serial_id, :parent => false, :except => SKIP
before_filter :load_pull, :except => SKIP
load_and_authorize_resource :issue, :through => :project, :find_by => :serial_id, :parent => false, :except => :autocomplete_base_project
before_filter :load_pull, :except => :autocomplete_base_project
def new
@pull = PullRequest.default_base_project(@project).pull_requests.new
@pull.issue = @project.issues.new
if params[:pull_request] && params[:pull_request][:issue_attributes]
@pull.issue.title = params[:pull_request][:issue_attributes][:title].presence
@pull.issue.body = params[:pull_request][:issue_attributes][:body].presence
base_project = (Project.find(params[:base_project_id]) if params[:base_project_id]) || PullRequest.default_base_project(@project)
authorize! :read, base_project
@pull = base_project.pull_requests.new
@pull.issue = base_project.issues.new
if pull_params && pull_params[:issue_attributes]
@pull.issue.title = pull_params[:issue_attributes][:title].presence
@pull.issue.body = pull_params[:issue_attributes][:body].presence
end
@pull.head_project = @project
@pull.base_ref = (params[:pull_request][:base_ref].presence if params[:pull_request]) || @pull.base_project.default_branch
@pull.head_ref = params[:treeish].presence || (params[:pull_request][:head_ref].presence if params[:pull_request]) || @pull.head_project.default_branch
@pull.base_ref = (pull_params[:base_ref].presence if pull_params) || @pull.base_project.default_branch
@pull.head_ref = params[:treeish].presence || (pull_params[:head_ref].presence if pull_params) || @pull.head_project.default_branch
@pull.check(false) # don't make event transaction
if @pull.status == 'already'
@pull.destroy
@ -28,9 +31,15 @@ class Projects::PullRequestsController < Projects::BaseController
end
def create
@pull = @project.pull_requests.new(params[:pull_request])
@pull.issue.user, @pull.issue.project = current_user, @pull.base_project
@pull.base_project, @pull.head_project = PullRequest.default_base_project(@project), @project
unless pull_params
raise 'expect pull_request params' # for debug
redirect :back
end
base_project = Project.find(params[:base_project_id])
authorize! :read, base_project
@pull = base_project.pull_requests.new pull_params
@pull.issue.user, @pull.issue.project, @pull.head_project = current_user, base_project, @project
if @pull.save
@pull.check(false) # don't make event transaction
@ -45,6 +54,7 @@ class Projects::PullRequestsController < Projects::BaseController
else
flash[:error] = t('flash.pull_request.save_error')
flash[:warning] = @pull.errors.full_messages.join('. ')
@commits = @diff = @stats = nil
render :new
end
end
@ -67,39 +77,33 @@ class Projects::PullRequestsController < Projects::BaseController
load_diff_commits_data
end
def autocomplete_base_project_name
def autocomplete_base_project
#Maybe slow? ILIKE?
items = Project.accessible_by(current_ability, :membered)
items << PullRequest.default_base_project(@project)
logger.debug "items.count is #{items.count}"
items.select! {|e| Regexp.new(params[:term].downcase).match e.name.downcase}
items.uniq!
render :json => json_for_autocomplete(items, 'full_name')
end
render :json => json_for_autocomplete_base(items)#, :full_name, [:branches])
def autocomplete_head_project_name
items = Project.accessible_by(current_ability, :membered)
render :json => json_for_autocomplete(items, 'full_name')
end
def autocomplete_base_ref
project = PullRequest.default_base_project(@project)
items = (project.branches + project.tags).select {|e| Regexp.new(params[:term].downcase).match e.name.downcase}
render :json => json_for_autocomplete_ref(items)
end
def autocomplete_head_ref
items = (@project.branches + @project.tags).select {|e| Regexp.new(params[:term].downcase).match e.name.downcase}
render :json => json_for_autocomplete_ref(items)
end
protected
def json_for_autocomplete_ref(items)
items.collect do |item|
{"id" => item.name, "label" => item.name, "value" => item.name}
def pull_params
@pull_params ||= params[:pull_request].presence
end
def json_for_autocomplete_base items
items.collect do |project|
hash = {"id" => project.id.to_s, "label" => project.full_name, "value" => project.full_name}
hash[:refs] = project.branches_and_tags.map &:name
hash
end
end
def load_pull
@issue ||= @issues.first #FIXME!
@issue ||= @issues.first #FIXME! merge action create @issues?
if params[:action].to_sym != :index
@pull = @project.pull_requests.joins(:issue).where(:issues => {:id => @issue.id}).readonly(false).first
else

View File

@ -114,7 +114,7 @@ class Ability
can([:create, :merge], Issue) {|issue| can? :write, issue.project}
can([:update, :destroy], Issue) {|issue| issue.user_id == user.id or local_admin?(issue.project)}
cannot :manage, Issue, :project => {:has_issues => false} # switch off issues
can([:autocomplete_base_ref, :autocomplete_head_ref], Issue, read_relations_for('issues', 'projects')) {|issue| can? :read, issue.project rescue nil}
can(:autocomplete_base_project, Issue, read_relations_for('issues', 'projects')) {|issue| can? :read, issue.project rescue nil}
can(:create, Comment) {|comment| can? :read, comment.project}
can(:update, Comment) {|comment| comment.user_id == user.id or local_admin?(comment.project || comment.commentable.project)}

View File

@ -102,6 +102,10 @@ class Project < ActiveRecord::Base
self.git_repository.branches
end
def branches_and_tags
branches + tags
end
def last_active_branch
@last_active_branch ||= branches.inject do |r, c|
r_last = r.commit.committed_date || r.commit.authored_date unless r.nil?
@ -232,7 +236,7 @@ class Project < ActiveRecord::Base
end
def full_name
"#{owner.uname}/#{name}"
@full_name ||= "#{owner.uname}/#{name}"
end
protected

View File

@ -16,23 +16,25 @@
=form_for @pull, :url => (@pull.status != 'already' ? project_pull_requests_path : new_project_pull_requests_path), :html => {:class => 'well well-large'} do |f|
.leftlist=f.label :base_project, t('.base_project'), :class => :label
.rightlist
= @pull.base_project.full_name
=#f.autocomplete_field :base_project, autocomplete_base_project_name_project_pull_requests_path, :value => @pull.base_project.full_name, :id_element => '#pull_request_base_project_id'
=#f.hidden_field :base_project_id
=f.autocomplete_field :base_project, autocomplete_base_project_project_pull_requests_path, :value => @pull.base_project.full_name, :id_element => '#pull_request_base_project_id', :name => 'base_project'
=f.hidden_field :base_project_id, :name => 'base_project_id'
.both
.leftlist=f.label :base_ref, "#{t '.base_ref'} #{t '.refs'}", :class => :label
.rightlist=f.autocomplete_field :base_ref, autocomplete_base_ref_project_pull_requests_path, :value => @pull.base_ref
.rightlist
%input{:id => 'base_refs', :value => @pull.base_ref, :name => 'pull_request[base_ref]'}
.both
.leftlist=f.label :head_project, t('.head_project'), :class => :label
.rightlist
= @pull.head_project.full_name
=#f.autocomplete_field :head_project, autocomplete_head_project_name_project_pull_requests_path, :value => @pull.head_project.full_name, :id_element => '#pull_request_head_project_id'
=#f.hidden_field :head_project_id
=@pull.head_project.full_name
.both
.leftlist=f.label :head_ref, "#{t '.head_ref'} #{t '.refs'}", :class => :label
.rightlist=f.autocomplete_field :head_ref, autocomplete_head_ref_project_pull_requests_path, :value => @pull.head_ref
.rightlist
%input{:id => 'head_refs', :value => @pull.head_ref, :name => 'pull_request[head_ref]'}
.both
= f.fields_for :issue do |issue|
.leftlist
.rightlist=f.submit t('.update'), :class => 'btn btn-primary disabled', 'data-loading-text' => t('layout.processing')#, :id => 'create_pull'
.both
=f.fields_for :issue do |issue|
.leftlist=issue.label :title, t('activerecord.attributes.issue.title'), :class => :label
.rightlist=issue.text_field :title
.both
@ -47,4 +49,22 @@
.rightlist=f.submit t(@pull.status != 'already' ? '.submit' : '.update'), :class => 'btn btn-primary disabled', 'data-loading-text' => t('layout.processing')#, :id => 'create_pull'
.both
=render 'diff_commits_tabs' if @pull.status != 'already'
=render 'diff_commits_tabs' if @pull.status != 'already' && @stats != nil
:javascript
$(function() {
$('input#base_refs').autocomplete({
source: #{@pull.base_project.branches_and_tags.map &:name}
});
$('input#head_refs').autocomplete({
source: #{@project.branches_and_tags.map &:name}
});
$('#pull_request_base_project').on('autocompleteselect', function(event, data){
/* Do something here */
$('input#base_refs').autocomplete('option', 'source', data.item.refs);
alert('work?');
});
});

View File

@ -173,10 +173,7 @@ Rosa::Application.routes.draw do
resources :pull_requests, :except => [:destroy, :new, :index] do
collection do
post '/new' => 'pull_requests#new'
get :autocomplete_base_project_name
get :autocomplete_head_project_name
get :autocomplete_base_ref
get :autocomplete_head_ref
get :autocomplete_base_project
end
member do
put :merge, :as => 'merge'

View File

@ -17,7 +17,7 @@ describe Projects::PullRequestsController do
@another_user = FactoryGirl.create(:user)
@create_params = {:pull_request => {:issue_attributes => {:title => 'create', :body => 'creating'}, :base_ref => 'non_conflicts', :head_ref => 'master'},
:owner_name => @project.owner.uname, :project_name => @project.name}
:base_project_id => @project.id, :owner_name => @project.owner.uname, :project_name => @project.name}
@update_params = @create_params.merge(:pull_request => {:issue_attributes => {:title => 'update', :body => 'updating', :id => @pull.issue.id}}, :id => @pull.serial_id)
end
@ -59,12 +59,12 @@ describe Projects::PullRequestsController do
end
it "should not create same pull" do
post :create, @create_params.merge({:pull_request => {:issue_attributes => {:title => 'same', :body => 'creating'}, :head_ref => 'non_conflicts', :base_ref => 'master'}})
post :create, @create_params.merge({:pull_request => {:issue_attributes => {:title => 'same', :body => 'creating'}, :head_ref => 'non_conflicts', :base_ref => 'master'}, :base_project_id => @project.id})
PullRequest.joins(:issue).where(:issues => {:title => 'same', :body => 'creating'}).count.should == 0
end
it "should not create already up-to-date pull" do
post :create, @create_params.merge({:pull_request => {:issue_attributes => {:title => 'already', :body => 'creating'}, :base_ref => 'master', :head_ref => 'master'}})
post :create, @create_params.merge({:pull_request => {:issue_attributes => {:title => 'already', :body => 'creating'}, :base_ref => 'master', :head_ref => 'master'}, :base_project_id => @project.id})
PullRequest.joins(:issue).where(:issues => {:title => 'already', :body => 'creating'}).count.should == 0
end
end