diff --git a/app/controllers/projects/pull_requests_controller.rb b/app/controllers/projects/pull_requests_controller.rb index c38db6878..d30ab6712 100644 --- a/app/controllers/projects/pull_requests_controller.rb +++ b/app/controllers/projects/pull_requests_controller.rb @@ -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 diff --git a/app/models/ability.rb b/app/models/ability.rb index c38b090b8..57d309d48 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -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)} diff --git a/app/models/project.rb b/app/models/project.rb index b97eb6914..9b5ed2d4d 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -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 diff --git a/app/views/projects/pull_requests/new.html.haml b/app/views/projects/pull_requests/new.html.haml index 468ef14d6..f6d247c1d 100644 --- a/app/views/projects/pull_requests/new.html.haml +++ b/app/views/projects/pull_requests/new.html.haml @@ -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?'); + }); + }); + diff --git a/config/routes.rb b/config/routes.rb index cb31174e1..a35552d04 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -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' diff --git a/spec/controllers/projects/pull_requests_controller_spec.rb b/spec/controllers/projects/pull_requests_controller_spec.rb index ac3866c07..511244a23 100644 --- a/spec/controllers/projects/pull_requests_controller_spec.rb +++ b/spec/controllers/projects/pull_requests_controller_spec.rb @@ -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