From 2d7062d8fc5d4fc8fb8aba83947de7955cd41e3c Mon Sep 17 00:00:00 2001 From: Staicu Ionut Date: Wed, 24 Oct 2012 14:06:10 +0300 Subject: [PATCH 1/6] Added autofocus for issue title --- app/views/issues/_form.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/issues/_form.html.haml b/app/views/issues/_form.html.haml index ec3edce0..2ba72975 100644 --- a/app/views/issues/_form.html.haml +++ b/app/views/issues/_form.html.haml @@ -12,7 +12,7 @@ = f.label :title do %strong= "Subject *" .input - = f.text_field :title, maxlength: 255, class: "xxlarge gfm-input" + = f.text_field :title, maxlength: 255, class: "xxlarge gfm-input", autofocus: true .issue_middle_block .issue_assignee = f.label :assignee_id do From fd0aca122545bf7e4911f45aaff7bcd960accc7b Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 24 Oct 2012 14:20:53 +0300 Subject: [PATCH 2/6] Feature implemented --- app/controllers/team_members_controller.rb | 8 ++++++++ app/models/users_project.rb | 16 ++++++++++++++++ app/views/team_members/import.html.haml | 17 +++++++++++++++++ app/views/team_members/index.html.haml | 9 +++++++-- config/routes.rb | 11 ++++++++++- 5 files changed, 58 insertions(+), 3 deletions(-) create mode 100644 app/views/team_members/import.html.haml diff --git a/app/controllers/team_members_controller.rb b/app/controllers/team_members_controller.rb index d0b699f6..37ed74b2 100644 --- a/app/controllers/team_members_controller.rb +++ b/app/controllers/team_members_controller.rb @@ -43,4 +43,12 @@ class TeamMembersController < ProjectResourceController format.js { render nothing: true } end end + + def apply_import + giver = Project.find(params[:source_project_id]) + status = UsersProject.import_team(giver, project) + notice = status ? "Succesfully imported" : "Import failed" + + redirect_to project_team_members_path(project), notice: notice + end end diff --git a/app/models/users_project.rb b/app/models/users_project.rb index e336fac3..3c1fe213 100644 --- a/app/models/users_project.rb +++ b/app/models/users_project.rb @@ -21,6 +21,22 @@ class UsersProject < ActiveRecord::Base delegate :name, :email, to: :user, prefix: true class << self + def import_team(source_project, target_project) + UsersProject.transaction do + team = source_project.users_projects.all + + team.each do |tm| + # Skip if user already present in team + next if target_project.users.include?(tm.user) + + new_tm = tm.dup + new_tm.id = nil + new_tm.project_id = target_project.id + new_tm.save + end + end + end + def bulk_delete(project, user_ids) UsersProject.transaction do UsersProject.where(:user_id => user_ids, :project_id => project.id).each do |users_project| diff --git a/app/views/team_members/import.html.haml b/app/views/team_members/import.html.haml new file mode 100644 index 00000000..59a27fd3 --- /dev/null +++ b/app/views/team_members/import.html.haml @@ -0,0 +1,17 @@ += render "projects/project_head" + +%h3.page_title + = "Import team from another project" +%hr +%p.slead + Read more about team import #{link_to "here", '#', class: 'vlink'}. += form_tag apply_import_project_team_members_path(@project), method: 'post' do + %p.slead Choose project you want to use as team source: + .padded + = label_tag :source_project_id, "Project" + .input= select_tag(:source_project_id, options_from_collection_for_select(current_user.projects, :id, :name), prompt: "Select project", class: "chosen xxlarge", required: true) + + .actions + = submit_tag 'Save', class: "btn save-btn" + = link_to "Cancel", project_team_index_path(@project), class: "btn cancel-btn" + diff --git a/app/views/team_members/index.html.haml b/app/views/team_members/index.html.haml index b3b7b72a..ca3edcf7 100644 --- a/app/views/team_members/index.html.haml +++ b/app/views/team_members/index.html.haml @@ -5,9 +5,14 @@ - if can? current_user, :admin_team_member, @project %p.slead - = link_to new_project_team_member_path(@project), class: "btn small right", title: "New Team Member" do - New Team Member Read more about project permissions %strong= link_to "here", help_permissions_path, class: "vlink" + %span.right + = link_to import_project_team_members_path(@project), class: "btn small grouped", title: "Import team from another project" do + Import team from another project + = link_to new_project_team_member_path(@project), class: "btn success small grouped", title: "New Team Member" do + New Team Member + + .clearfix = render partial: "team_members/team", locals: {project: @project} diff --git a/config/routes.rb b/config/routes.rb index de5261d2..adaf6a1e 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -188,7 +188,6 @@ Gitlab::Application.routes.draw do :via => [:get, :post], constraints: {from: /.+/, to: /.+/} resources :team, controller: 'team_members', only: [:index] - resources :team_members resources :milestones resources :labels, only: [:index] resources :issues do @@ -199,6 +198,16 @@ Gitlab::Application.routes.draw do end end + resources :team_members do + collection do + + # Used for import team + # from another project + get :import + post :apply_import + end + end + resources :notes, only: [:index, :create, :destroy] do collection do post :preview From b7a9e41bd269e2b5519928c35592aad96d3707c6 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 24 Oct 2012 14:52:17 +0300 Subject: [PATCH 3/6] Handle perfomance issue with team import. Model specs --- app/models/users_project.rb | 31 ++++++++++++++++++++--------- spec/models/users_project_spec.rb | 33 +++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 9 deletions(-) diff --git a/app/models/users_project.rb b/app/models/users_project.rb index 3c1fe213..967c78f2 100644 --- a/app/models/users_project.rb +++ b/app/models/users_project.rb @@ -22,19 +22,32 @@ class UsersProject < ActiveRecord::Base class << self def import_team(source_project, target_project) - UsersProject.transaction do - team = source_project.users_projects.all + UsersProject.without_repository_callback do + UsersProject.transaction do + team = source_project.users_projects.all - team.each do |tm| - # Skip if user already present in team - next if target_project.users.include?(tm.user) + team.each do |tm| + # Skip if user already present in team + next if target_project.users.include?(tm.user) - new_tm = tm.dup - new_tm.id = nil - new_tm.project_id = target_project.id - new_tm.save + new_tm = tm.dup + new_tm.id = nil + new_tm.project_id = target_project.id + new_tm.save + end end end + + target_project.update_repository + true + rescue + false + end + + def without_repository_callback + UsersProject.skip_callback(:destroy, :after, :update_repository) + yield + UsersProject.set_callback(:destroy, :after, :update_repository) end def bulk_delete(project, user_ids) diff --git a/spec/models/users_project_spec.rb b/spec/models/users_project_spec.rb index 5b6516b3..2ad9a0bd 100644 --- a/spec/models/users_project_spec.rb +++ b/spec/models/users_project_spec.rb @@ -35,4 +35,37 @@ describe UsersProject do it { should respond_to(:user_name) } it { should respond_to(:user_email) } end + + describe :import_team do + before do + @abilities = Six.new + @abilities << Ability + + @project_1 = create :project + @project_2 = create :project + + @user_1 = create :user + @user_2 = create :user + + @project_1.add_access @user_1, :write + @project_2.add_access @user_2, :read + + @status = UsersProject.import_team(@project_1, @project_2) + end + + it { @status.should be_true } + + describe 'project 2 should get user 1 as developer. user_2 should not be changed' do + it { @project_2.users.should include(@user_1) } + it { @project_2.users.should include(@user_2) } + + it { @abilities.allowed?(@user_1, :write_project, @project_2).should be_true } + it { @abilities.allowed?(@user_2, :read_project, @project_2).should be_true } + end + + describe 'project 1 should not be changed' do + it { @project_1.users.should include(@user_1) } + it { @project_1.users.should_not include(@user_2) } + end + end end From 6f4576b7436ff4573b28ab8305796e96bb2aed29 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 24 Oct 2012 15:23:04 +0300 Subject: [PATCH 4/6] Spinach feature --- app/views/team_members/import.html.haml | 2 +- features/project/team_management.feature | 7 +++++++ .../steps/project/project_team_management.rb | 20 +++++++++++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/app/views/team_members/import.html.haml b/app/views/team_members/import.html.haml index 59a27fd3..34f7fb03 100644 --- a/app/views/team_members/import.html.haml +++ b/app/views/team_members/import.html.haml @@ -12,6 +12,6 @@ .input= select_tag(:source_project_id, options_from_collection_for_select(current_user.projects, :id, :name), prompt: "Select project", class: "chosen xxlarge", required: true) .actions - = submit_tag 'Save', class: "btn save-btn" + = submit_tag 'Import', class: "btn save-btn" = link_to "Cancel", project_team_index_path(@project), class: "btn cancel-btn" diff --git a/features/project/team_management.feature b/features/project/team_management.feature index ae0c459f..0ac37620 100644 --- a/features/project/team_management.feature +++ b/features/project/team_management.feature @@ -32,3 +32,10 @@ Feature: Project Team management And I click link "Remove from team" Then I visit project "Shop" team page And I should not see "Sam" in team list + + Scenario: Import team from another project + Given I own project "Website" + And "Mike" is "Website" reporter + And I click link "Import team from another project" + When I submit "Website" project for import team + Then I should see "Mike" in team list as "Reporter" diff --git a/features/steps/project/project_team_management.rb b/features/steps/project/project_team_management.rb index 7beca257..5c3a9b31 100644 --- a/features/steps/project/project_team_management.rb +++ b/features/steps/project/project_team_management.rb @@ -86,4 +86,24 @@ class ProjectTeamManagement < Spinach::FeatureSteps project = Project.find_by_name("Shop") project.add_access(user, :write) end + + Given 'I own project "Website"' do + @project = Factory :project, :name => "Website" + @project.add_access(@user, :admin) + end + + And '"Mike" is "Website" reporter' do + user = User.find_by_name("Mike") + project = Project.find_by_name("Website") + project.add_access(user, :read) + end + + And 'I click link "Import team from another project"' do + click_link "Import team from another project" + end + + When 'I submit "Website" project for import team' do + select 'Website', from: 'source_project_id' + click_button 'Import' + end end From a7efeb378135a9d2a263b4d14d24c462d4c8eb29 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 24 Oct 2012 15:25:08 +0300 Subject: [PATCH 5/6] Fix chrome issues list --- app/views/issues/_show.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/issues/_show.html.haml b/app/views/issues/_show.html.haml index 4b6823f5..8aa92ebf 100644 --- a/app/views/issues/_show.html.haml +++ b/app/views/issues/_show.html.haml @@ -16,7 +16,7 @@ = link_to 'Reopen', project_issue_path(issue.project, issue, issue: {closed: false }, status_only: true), method: :put, class: "btn small grouped reopen_issue", remote: true - else = link_to 'Close', project_issue_path(issue.project, issue, issue: {closed: true }, status_only: true), method: :put, class: "btn small grouped close_issue", remote: true - = link_to edit_project_issue_path(issue.project, issue), class: "btn small edit-issue-link", remote: true do + = link_to edit_project_issue_path(issue.project, issue), class: "btn small edit-issue-link grouped", remote: true do %i.icon-edit Edit From 5add5f760ebd87e9318f13d3f2ae4e4a4ddbe3ae Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 24 Oct 2012 16:13:20 +0300 Subject: [PATCH 6/6] up to 3.0.3 --- CHANGELOG | 4 ++++ VERSION | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 56733013..a4debcc4 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,7 @@ +v 3.0.3 + - Fixed bug with issues list in Chrome + - New Feature: Import team from another project + v 3.0.2 - Fixed gitlab:app:setup - Fixed application error on empty project in admin area diff --git a/VERSION b/VERSION index b5021469..75a22a26 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.0.2 +3.0.3