Merge branch 'master' into stable
This commit is contained in:
commit
7ecfaccf14
12 changed files with 138 additions and 6 deletions
|
@ -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
|
v 3.0.2
|
||||||
- Fixed gitlab:app:setup
|
- Fixed gitlab:app:setup
|
||||||
- Fixed application error on empty project in admin area
|
- Fixed application error on empty project in admin area
|
||||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
3.0.2
|
3.0.3
|
||||||
|
|
|
@ -43,4 +43,12 @@ class TeamMembersController < ProjectResourceController
|
||||||
format.js { render nothing: true }
|
format.js { render nothing: true }
|
||||||
end
|
end
|
||||||
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
|
end
|
||||||
|
|
|
@ -21,6 +21,35 @@ class UsersProject < ActiveRecord::Base
|
||||||
delegate :name, :email, to: :user, prefix: true
|
delegate :name, :email, to: :user, prefix: true
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
|
def import_team(source_project, target_project)
|
||||||
|
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)
|
||||||
|
|
||||||
|
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)
|
def bulk_delete(project, user_ids)
|
||||||
UsersProject.transaction do
|
UsersProject.transaction do
|
||||||
UsersProject.where(:user_id => user_ids, :project_id => project.id).each do |users_project|
|
UsersProject.where(:user_id => user_ids, :project_id => project.id).each do |users_project|
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
= f.label :title do
|
= f.label :title do
|
||||||
%strong= "Subject *"
|
%strong= "Subject *"
|
||||||
.input
|
.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_middle_block
|
||||||
.issue_assignee
|
.issue_assignee
|
||||||
= f.label :assignee_id do
|
= f.label :assignee_id do
|
||||||
|
|
|
@ -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
|
= 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
|
- 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 '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
|
%i.icon-edit
|
||||||
Edit
|
Edit
|
||||||
|
|
||||||
|
|
17
app/views/team_members/import.html.haml
Normal file
17
app/views/team_members/import.html.haml
Normal file
|
@ -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 'Import', class: "btn save-btn"
|
||||||
|
= link_to "Cancel", project_team_index_path(@project), class: "btn cancel-btn"
|
||||||
|
|
|
@ -5,9 +5,14 @@
|
||||||
|
|
||||||
- if can? current_user, :admin_team_member, @project
|
- if can? current_user, :admin_team_member, @project
|
||||||
%p.slead
|
%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
|
Read more about project permissions
|
||||||
%strong= link_to "here", help_permissions_path, class: "vlink"
|
%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}
|
= render partial: "team_members/team", locals: {project: @project}
|
||||||
|
|
|
@ -188,7 +188,6 @@ Gitlab::Application.routes.draw do
|
||||||
:via => [:get, :post], constraints: {from: /.+/, to: /.+/}
|
:via => [:get, :post], constraints: {from: /.+/, to: /.+/}
|
||||||
|
|
||||||
resources :team, controller: 'team_members', only: [:index]
|
resources :team, controller: 'team_members', only: [:index]
|
||||||
resources :team_members
|
|
||||||
resources :milestones
|
resources :milestones
|
||||||
resources :labels, only: [:index]
|
resources :labels, only: [:index]
|
||||||
resources :issues do
|
resources :issues do
|
||||||
|
@ -199,6 +198,16 @@ Gitlab::Application.routes.draw do
|
||||||
end
|
end
|
||||||
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
|
resources :notes, only: [:index, :create, :destroy] do
|
||||||
collection do
|
collection do
|
||||||
post :preview
|
post :preview
|
||||||
|
|
|
@ -32,3 +32,10 @@ Feature: Project Team management
|
||||||
And I click link "Remove from team"
|
And I click link "Remove from team"
|
||||||
Then I visit project "Shop" team page
|
Then I visit project "Shop" team page
|
||||||
And I should not see "Sam" in team list
|
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"
|
||||||
|
|
|
@ -86,4 +86,24 @@ class ProjectTeamManagement < Spinach::FeatureSteps
|
||||||
project = Project.find_by_name("Shop")
|
project = Project.find_by_name("Shop")
|
||||||
project.add_access(user, :write)
|
project.add_access(user, :write)
|
||||||
end
|
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
|
end
|
||||||
|
|
|
@ -35,4 +35,37 @@ describe UsersProject do
|
||||||
it { should respond_to(:user_name) }
|
it { should respond_to(:user_name) }
|
||||||
it { should respond_to(:user_email) }
|
it { should respond_to(:user_email) }
|
||||||
end
|
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
|
end
|
||||||
|
|
Loading…
Reference in a new issue