Commit 18bd1c9d30e16783d750c7786cbcc7d350f4d0aa
Committed by
Dmitriy Zaporozhets
1 parent
7658f8c1
Exists in
master
and in
4 other branches
update all teams code. refactoring and some corrections
Showing
35 changed files
with
330 additions
and
281 deletions
Show diff stats
app/controllers/admin/teams/application_controller.rb
app/controllers/admin/teams/members_controller.rb
1 | 1 | class Admin::Teams::MembersController < Admin::Teams::ApplicationController |
2 | 2 | def new |
3 | 3 | @users = User.active |
4 | - @users = @users.not_in_team(@team) if @team.members.any? | |
4 | + @users = @users.not_in_team(user_team) if user_team.members.any? | |
5 | 5 | @users = UserDecorator.decorate @users |
6 | 6 | end |
7 | 7 | |
... | ... | @@ -10,10 +10,10 @@ class Admin::Teams::MembersController < Admin::Teams::ApplicationController |
10 | 10 | user_ids = params[:user_ids] |
11 | 11 | access = params[:default_project_access] |
12 | 12 | is_admin = params[:group_admin] |
13 | - @team.add_members(user_ids, access, is_admin) | |
13 | + user_team.add_members(user_ids, access, is_admin) | |
14 | 14 | end |
15 | 15 | |
16 | - redirect_to admin_team_path(@team), notice: 'Members was successfully added.' | |
16 | + redirect_to admin_team_path(user_team), notice: 'Members was successfully added into Team of users.' | |
17 | 17 | end |
18 | 18 | |
19 | 19 | def edit |
... | ... | @@ -22,24 +22,24 @@ class Admin::Teams::MembersController < Admin::Teams::ApplicationController |
22 | 22 | |
23 | 23 | def update |
24 | 24 | options = {default_projects_access: params[:default_project_access], group_admin: params[:group_admin]} |
25 | - if @team.update_membership(team_member, options) | |
26 | - redirect_to admin_team_path(@team), notice: 'Membership was successfully updated.' | |
25 | + if user_team.update_membership(team_member, options) | |
26 | + redirect_to admin_team_path(user_team), notice: "Membership for #{team_member.name} was successfully updated in Team of users." | |
27 | 27 | else |
28 | 28 | render :edit |
29 | 29 | end |
30 | 30 | end |
31 | 31 | |
32 | 32 | def destroy |
33 | - if @team.remove_member(team_member) | |
34 | - redirect_to admin_team_path(@team), notice: "Member was successfully removed from team." | |
33 | + if user_team.remove_member(team_member) | |
34 | + redirect_to admin_team_path(user_team), notice: "Member #{team_member.name} was successfully removed from Team of users." | |
35 | 35 | else |
36 | - redirect_to admin_team_members(@team), notice: "Something wrong." | |
36 | + redirect_to admin_team_members(user_team), notice: "Something is wrong." | |
37 | 37 | end |
38 | 38 | end |
39 | 39 | |
40 | 40 | protected |
41 | 41 | |
42 | 42 | def team_member |
43 | - @member ||= @team.members.find(params[:id]) | |
43 | + @member ||= user_team.members.find(params[:id]) | |
44 | 44 | end |
45 | 45 | end | ... | ... |
app/controllers/admin/teams/projects_controller.rb
1 | 1 | class Admin::Teams::ProjectsController < Admin::Teams::ApplicationController |
2 | 2 | def new |
3 | 3 | @projects = Project.scoped |
4 | - @projects = @projects.without_team(@team) if @team.projects.any? | |
4 | + @projects = @projects.without_team(user_team) if user_team.projects.any? | |
5 | 5 | #@projects.reject!(&:empty_repo?) |
6 | 6 | end |
7 | 7 | |
... | ... | @@ -9,10 +9,10 @@ class Admin::Teams::ProjectsController < Admin::Teams::ApplicationController |
9 | 9 | unless params[:project_ids].blank? |
10 | 10 | project_ids = params[:project_ids] |
11 | 11 | access = params[:greatest_project_access] |
12 | - @team.assign_to_projects(project_ids, access) | |
12 | + user_team.assign_to_projects(project_ids, access) | |
13 | 13 | end |
14 | 14 | |
15 | - redirect_to admin_team_path(@team), notice: 'Projects was successfully added.' | |
15 | + redirect_to admin_team_path(user_team), notice: 'Team of users was successfully assgned to projects.' | |
16 | 16 | end |
17 | 17 | |
18 | 18 | def edit |
... | ... | @@ -20,22 +20,22 @@ class Admin::Teams::ProjectsController < Admin::Teams::ApplicationController |
20 | 20 | end |
21 | 21 | |
22 | 22 | def update |
23 | - if @team.update_project_access(team_project, params[:greatest_project_access]) | |
24 | - redirect_to admin_team_path(@team), notice: 'Membership was successfully updated.' | |
23 | + if user_team.update_project_access(team_project, params[:greatest_project_access]) | |
24 | + redirect_to admin_team_path(user_team), notice: 'Access was successfully updated.' | |
25 | 25 | else |
26 | 26 | render :edit |
27 | 27 | end |
28 | 28 | end |
29 | 29 | |
30 | 30 | def destroy |
31 | - @team.resign_from_project(team_project) | |
32 | - redirect_to admin_team_path(@team), notice: 'Project was successfully removed.' | |
31 | + user_team.resign_from_project(team_project) | |
32 | + redirect_to admin_team_path(user_team), notice: 'Team of users was successfully reassigned from project.' | |
33 | 33 | end |
34 | 34 | |
35 | 35 | protected |
36 | 36 | |
37 | 37 | def team_project |
38 | - @project ||= @team.projects.find_by_path(params[:id]) | |
38 | + @project ||= user_team.projects.find_with_namespace(params[:id]) | |
39 | 39 | end |
40 | 40 | |
41 | 41 | end | ... | ... |
app/controllers/admin/teams_controller.rb
... | ... | @@ -24,12 +24,12 @@ class Admin::TeamsController < Admin::ApplicationController |
24 | 24 | end |
25 | 25 | |
26 | 26 | def create |
27 | - user_team = UserTeam.new(params[:user_team]) | |
28 | - user_team.path = user_team.name.dup.parameterize if user_team.name | |
29 | - user_team.owner = current_user | |
27 | + @team = UserTeam.new(params[:user_team]) | |
28 | + @team.path = @team.name.dup.parameterize if @team.name | |
29 | + @team.owner = current_user | |
30 | 30 | |
31 | - if user_team.save | |
32 | - redirect_to admin_team_path(user_team), notice: 'UserTeam was successfully created.' | |
31 | + if @team.save | |
32 | + redirect_to admin_team_path(@team), notice: 'Team of users was successfully created.' | |
33 | 33 | else |
34 | 34 | render action: "new" |
35 | 35 | end |
... | ... | @@ -44,7 +44,7 @@ class Admin::TeamsController < Admin::ApplicationController |
44 | 44 | end |
45 | 45 | |
46 | 46 | if user_team.update_attributes(user_team_params) |
47 | - redirect_to admin_team_path(user_team), notice: 'UserTeam was successfully updated.' | |
47 | + redirect_to admin_team_path(user_team), notice: 'Team of users was successfully updated.' | |
48 | 48 | else |
49 | 49 | render action: "edit" |
50 | 50 | end |
... | ... | @@ -53,7 +53,7 @@ class Admin::TeamsController < Admin::ApplicationController |
53 | 53 | def destroy |
54 | 54 | user_team.destroy |
55 | 55 | |
56 | - redirect_to admin_user_teams_path, notice: 'UserTeam was successfully deleted.' | |
56 | + redirect_to admin_user_teams_path, notice: 'Team of users was successfully deleted.' | |
57 | 57 | end |
58 | 58 | |
59 | 59 | protected | ... | ... |
app/controllers/application_controller.rb
... | ... | @@ -94,6 +94,14 @@ class ApplicationController < ActionController::Base |
94 | 94 | return access_denied! unless can?(current_user, :download_code, project) |
95 | 95 | end |
96 | 96 | |
97 | + def authorize_manage_user_team! | |
98 | + return access_denied! unless user_team.present? && can?(current_user, :manage_user_team, user_team) | |
99 | + end | |
100 | + | |
101 | + def authorize_admin_user_team! | |
102 | + return access_denied! unless user_team.present? && can?(current_user, :admin_user_team, user_team) | |
103 | + end | |
104 | + | |
97 | 105 | def access_denied! |
98 | 106 | render "errors/access_denied", layout: "errors", status: 404 |
99 | 107 | end |
... | ... | @@ -135,4 +143,5 @@ class ApplicationController < ActionController::Base |
135 | 143 | def dev_tools |
136 | 144 | Rack::MiniProfiler.authorize_request |
137 | 145 | end |
146 | + | |
138 | 147 | end | ... | ... |
app/controllers/team_members_controller.rb
app/controllers/teams/application_controller.rb
... | ... | @@ -5,11 +5,7 @@ class Teams::ApplicationController < ApplicationController |
5 | 5 | protected |
6 | 6 | |
7 | 7 | def user_team |
8 | - @user_team ||= UserTeam.find_by_path(params[:team_id]) | |
9 | - end | |
10 | - | |
11 | - def authorize_manage_user_team! | |
12 | - return access_denied! unless can?(current_user, :manage_user_team, user_team) | |
8 | + @team ||= UserTeam.find_by_path(params[:team_id]) | |
13 | 9 | end |
14 | 10 | |
15 | 11 | end | ... | ... |
app/controllers/teams/members_controller.rb
1 | 1 | class Teams::MembersController < Teams::ApplicationController |
2 | - # Authorize | |
2 | + | |
3 | 3 | skip_before_filter :authorize_manage_user_team!, only: [:index] |
4 | 4 | |
5 | 5 | def index |
6 | - @members = @user_team.members | |
7 | - end | |
8 | - | |
9 | - def show | |
10 | - @team_member = @user_team.members.find(params[:id]) | |
11 | - @events = @team_member.recent_events.limit(7) | |
6 | + @members = user_team.members | |
12 | 7 | end |
13 | 8 | |
14 | 9 | def new |
15 | - @team_member = @user_team.members.new | |
10 | + @users = User.active | |
11 | + @users = @users.not_in_team(user_team) if user_team.members.any? | |
12 | + @users = UserDecorator.decorate @users | |
16 | 13 | end |
17 | 14 | |
18 | 15 | def create |
19 | - users = User.where(id: params[:user_ids]) | |
16 | + unless params[:user_ids].blank? | |
17 | + user_ids = params[:user_ids] | |
18 | + access = params[:default_project_access] | |
19 | + is_admin = params[:group_admin] | |
20 | + user_team.add_members(user_ids, access, is_admin) | |
21 | + end | |
20 | 22 | |
21 | - @project.team << [users, params[:default_project_access]] | |
23 | + redirect_to team_path(user_team), notice: 'Members was successfully added into Team of users.' | |
24 | + end | |
22 | 25 | |
23 | - if params[:redirect_to] | |
24 | - redirect_to params[:redirect_to] | |
25 | - else | |
26 | - redirect_to project_team_index_path(@project) | |
27 | - end | |
26 | + def edit | |
27 | + team_member | |
28 | 28 | end |
29 | 29 | |
30 | 30 | def update |
31 | - @team_member = @user_team.members.find(params[:id]) | |
32 | - @team_member.update_attributes(params[:team_member]) | |
33 | - | |
34 | - unless @team_member.valid? | |
35 | - flash[:alert] = "User should have at least one role" | |
31 | + options = {default_projects_access: params[:default_project_access], group_admin: params[:group_admin]} | |
32 | + if user_team.update_membership(team_member, options) | |
33 | + redirect_to team_path(user_team), notice: "Membership for #{team_member.name} was successfully updated in Team of users." | |
34 | + else | |
35 | + render :edit | |
36 | 36 | end |
37 | - redirect_to team_member_path(@project) | |
38 | 37 | end |
39 | 38 | |
40 | 39 | def destroy |
41 | - @team_member = project.users_projects.find(params[:id]) | |
42 | - @team_member.destroy | |
43 | - | |
44 | - respond_to do |format| | |
45 | - format.html { redirect_to project_team_index_path(@project) } | |
46 | - format.js { render nothing: true } | |
40 | + if user_team.remove_member(team_member) | |
41 | + redirect_to team_path(user_team), notice: "Member #{team_member.name} was successfully removed from Team of users." | |
42 | + else | |
43 | + redirect_to team_members(user_team), notice: "Something is wrong." | |
47 | 44 | end |
48 | 45 | end |
49 | 46 | |
50 | - def apply_import | |
51 | - giver = Project.find(params[:source_project_id]) | |
52 | - status = @project.team.import(giver) | |
53 | - notice = status ? "Succesfully imported" : "Import failed" | |
47 | + protected | |
54 | 48 | |
55 | - redirect_to project_team_members_path(project), notice: notice | |
49 | + def team_member | |
50 | + @member ||= user_team.members.find(params[:id]) | |
56 | 51 | end |
57 | 52 | |
58 | 53 | end | ... | ... |
app/controllers/teams/projects_controller.rb
... | ... | @@ -8,9 +8,12 @@ class Teams::ProjectsController < Teams::ApplicationController |
8 | 8 | end |
9 | 9 | |
10 | 10 | def new |
11 | - @projects = Project.scoped | |
12 | - @projects = @projects.without_team(user_team) if user_team.projects.any? | |
11 | + user_team | |
12 | + @avaliable_projects = Project.scoped | |
13 | + @avaliable_projects = @avaliable_projects.without_team(user_team) if user_team.projects.any? | |
13 | 14 | #@projects.reject!(&:empty_repo?) |
15 | + | |
16 | + redirect_to team_projects_path(user_team), notice: "No avalible projects." unless @avaliable_projects.any? | |
14 | 17 | end |
15 | 18 | |
16 | 19 | def create |
... | ... | @@ -20,7 +23,7 @@ class Teams::ProjectsController < Teams::ApplicationController |
20 | 23 | user_team.assign_to_projects(project_ids, access) |
21 | 24 | end |
22 | 25 | |
23 | - redirect_to admin_team_path(user_team), notice: 'Projects was successfully added.' | |
26 | + redirect_to team_projects_path(user_team), notice: 'Team of users was successfully assgned to projects.' | |
24 | 27 | end |
25 | 28 | |
26 | 29 | def edit |
... | ... | @@ -29,7 +32,7 @@ class Teams::ProjectsController < Teams::ApplicationController |
29 | 32 | |
30 | 33 | def update |
31 | 34 | if user_team.update_project_access(team_project, params[:greatest_project_access]) |
32 | - redirect_to admin_team_path(user_team), notice: 'Membership was successfully updated.' | |
35 | + redirect_to team_projects_path(user_team), notice: 'Access was successfully updated.' | |
33 | 36 | else |
34 | 37 | render :edit |
35 | 38 | end |
... | ... | @@ -37,13 +40,13 @@ class Teams::ProjectsController < Teams::ApplicationController |
37 | 40 | |
38 | 41 | def destroy |
39 | 42 | user_team.resign_from_project(team_project) |
40 | - redirect_to admin_team_path(user_team), notice: 'Project was successfully removed.' | |
43 | + redirect_to team_projects_path(user_team), notice: 'Team of users was successfully reassigned from project.' | |
41 | 44 | end |
42 | 45 | |
43 | 46 | private |
44 | 47 | |
45 | 48 | def team_project |
46 | - @project ||= @team.projects.find_by_path(params[:id]) | |
49 | + @project ||= user_team.projects.find_with_namespace(params[:id]) | |
47 | 50 | end |
48 | 51 | |
49 | 52 | end | ... | ... |
app/controllers/teams_controller.rb
1 | 1 | class TeamsController < ApplicationController |
2 | - respond_to :html | |
3 | - layout 'user_team', only: [:show, :edit, :update, :destroy, :issues, :merge_requests, :search] | |
2 | + # Authorize | |
3 | + before_filter :authorize_manage_user_team! | |
4 | + before_filter :authorize_admin_user_team! | |
4 | 5 | |
5 | - before_filter :user_team, only: [:show, :edit, :update, :destroy, :issues, :merge_requests, :search] | |
6 | - before_filter :projects, only: [:show, :edit, :update, :destroy, :issues, :merge_requests, :search] | |
6 | + # Skip access control on public section | |
7 | + skip_before_filter :authorize_manage_user_team!, only: [:index, :show, :new, :destroy, :create, :search, :issues, :merge_requests] | |
8 | + skip_before_filter :authorize_admin_user_team!, only: [:index, :show, :new, :create, :search, :issues, :merge_requests] | |
7 | 9 | |
8 | - # Authorize | |
9 | - before_filter :authorize_manage_user_team!, only: [:edit, :update] | |
10 | - before_filter :authorize_admin_user_team!, only: [:destroy] | |
10 | + layout 'user_team', only: [:show, :edit, :update, :destroy, :issues, :merge_requests, :search] | |
11 | 11 | |
12 | 12 | def index |
13 | - @teams = UserTeam.all | |
13 | + @teams = UserTeam.order('name ASC') | |
14 | 14 | end |
15 | 15 | |
16 | 16 | def show |
17 | - @events = Event.in_projects(project_ids).limit(20).offset(params[:offset] || 0) | |
18 | - | |
19 | - respond_to do |format| | |
20 | - format.html | |
21 | - format.js | |
22 | - format.atom { render layout: false } | |
23 | - end | |
17 | + user_team | |
18 | + projects | |
19 | + @events = Event.in_projects(user_team.project_ids).limit(20).offset(params[:offset] || 0) | |
24 | 20 | end |
25 | 21 | |
26 | 22 | def edit |
27 | - | |
23 | + user_team | |
28 | 24 | end |
29 | 25 | |
30 | 26 | def update |
... | ... | @@ -58,56 +54,37 @@ class TeamsController < ApplicationController |
58 | 54 | |
59 | 55 | # Get authored or assigned open merge requests |
60 | 56 | def merge_requests |
61 | - @merge_requests = MergeRequest.of_user_team(@user_team) | |
57 | + @merge_requests = MergeRequest.of_user_team(user_team) | |
62 | 58 | @merge_requests = FilterContext.new(@merge_requests, params).execute |
63 | 59 | @merge_requests = @merge_requests.recent.page(params[:page]).per(20) |
64 | 60 | end |
65 | 61 | |
66 | 62 | # Get only assigned issues |
67 | 63 | def issues |
68 | - @issues = Issue.of_user_team(@user_team) | |
64 | + @issues = Issue.of_user_team(user_team) | |
69 | 65 | @issues = FilterContext.new(@issues, params).execute |
70 | 66 | @issues = @issues.recent.page(params[:page]).per(20) |
71 | 67 | @issues = @issues.includes(:author, :project) |
72 | - | |
73 | - respond_to do |format| | |
74 | - format.html | |
75 | - format.atom { render layout: false } | |
76 | - end | |
77 | 68 | end |
78 | 69 | |
79 | 70 | def search |
80 | - result = SearchContext.new(project_ids, params).execute | |
71 | + result = SearchContext.new(user_team.project_ids, params).execute | |
81 | 72 | |
82 | 73 | @projects = result[:projects] |
83 | 74 | @merge_requests = result[:merge_requests] |
84 | 75 | @issues = result[:issues] |
85 | 76 | @wiki_pages = result[:wiki_pages] |
77 | + @teams = result[:teams] | |
86 | 78 | end |
87 | 79 | |
88 | 80 | protected |
89 | 81 | |
90 | - def user_team | |
91 | - @user_team ||= UserTeam.find_by_path(params[:id]) | |
92 | - end | |
93 | - | |
94 | 82 | def projects |
95 | 83 | @projects ||= user_team.projects.sorted_by_activity |
96 | 84 | end |
97 | 85 | |
98 | - def project_ids | |
99 | - projects.map(&:id) | |
100 | - end | |
101 | - | |
102 | - def authorize_manage_user_team! | |
103 | - unless user_team.present? or can?(current_user, :manage_user_team, user_team) | |
104 | - return render_404 | |
105 | - end | |
86 | + def user_team | |
87 | + @team ||= UserTeam.find_by_path(params[:id]) | |
106 | 88 | end |
107 | 89 | |
108 | - def authorize_admin_user_team! | |
109 | - unless user_team.owner == current_user || current_user.admin? | |
110 | - return render_404 | |
111 | - end | |
112 | - end | |
113 | 90 | end | ... | ... |
app/views/admin/teams/index.html.haml
... | ... | @@ -34,4 +34,5 @@ |
34 | 34 | %td.bgred |
35 | 35 | = link_to 'Rename', edit_admin_team_path(team), id: "edit_#{dom_id(team)}", class: "btn small" |
36 | 36 | = link_to 'Destroy', admin_team_path(team), confirm: "REMOVE #{team.name}? Are you sure?", method: :delete, class: "btn small danger" |
37 | + | |
37 | 38 | = paginate @teams, theme: "admin" | ... | ... |
app/views/admin/teams/new.html.haml
... | ... | @@ -14,8 +14,6 @@ |
14 | 14 | %hr |
15 | 15 | .padded |
16 | 16 | %ul |
17 | - %li Team is kind of directory for several projects | |
18 | - %li All created teams are private | |
17 | + %li All created teams are public (users can view who enter into team and which project are assigned for this team) | |
19 | 18 | %li People within a team see only projects they have access to |
20 | - %li All projects of team will be stored in team directory | |
21 | - %li You will be able to move existing projects into team | |
19 | + %li You will be able to assign existing projects for team | ... | ... |
app/views/admin/teams/show.html.haml
... | ... | @@ -40,54 +40,51 @@ |
40 | 40 | = link_to "Cancel", "#", class: "btn change-owner-cancel-link" |
41 | 41 | |
42 | 42 | %fieldset |
43 | - %legend Members (#{@team.members.count}) | |
44 | - %table#members_list | |
45 | - %thead | |
46 | - %tr | |
47 | - %th User name | |
48 | - %th Default project access | |
49 | - %th Team access | |
50 | - %th.cred Danger Zone! | |
51 | - - @team.members.each do |member| | |
52 | - %tr.member | |
53 | - %td | |
54 | - = link_to [:admin, member] do | |
55 | - = member.name | |
56 | - %small= "(#{member.email})" | |
57 | - %td= @team.human_default_projects_access(member) | |
58 | - %td= @team.admin?(member) ? "Admin" : "Member" | |
59 | - %td.bgred | |
60 | - = link_to 'Edit', edit_admin_team_member_path(@team, member), class: "btn small" | |
61 | - | |
62 | - = link_to 'Remove', admin_team_member_path(@team, member), confirm: 'Remove member from team. Are you sure?', method: :delete, class: "btn danger small" | |
63 | - %tr | |
64 | - %td | |
65 | - %td | |
66 | - %td | |
67 | - %td= link_to 'Add members', new_admin_team_member_path(@team), class: "btn primary", id: :add_members_to_team | |
43 | + %legend | |
44 | + Members (#{@team.members.count}) | |
45 | + %span= link_to 'Add members', new_admin_team_member_path(@team), class: "btn success small right", id: :add_members_to_team | |
46 | + - if @team.members.any? | |
47 | + %table#members_list | |
48 | + %thead | |
49 | + %tr | |
50 | + %th User name | |
51 | + %th Default project access | |
52 | + %th Team access | |
53 | + %th.cred.span3 Danger Zone! | |
54 | + - @team.members.each do |member| | |
55 | + %tr.member | |
56 | + %td | |
57 | + = link_to [:admin, member] do | |
58 | + = member.name | |
59 | + %small= "(#{member.email})" | |
60 | + %td= @team.human_default_projects_access(member) | |
61 | + %td= @team.admin?(member) ? "Admin" : "Member" | |
62 | + %td.bgred | |
63 | + = link_to 'Edit', edit_admin_team_member_path(@team, member), class: "btn small" | |
64 | + | |
65 | + = link_to 'Remove', admin_team_member_path(@team, member), confirm: 'Remove member from team. Are you sure?', method: :delete, class: "btn danger small" | |
68 | 66 | |
69 | 67 | %fieldset |
70 | - %legend Projects (#{@team.projects.count}) | |
71 | - %table#projects_list | |
72 | - %thead | |
73 | - %tr | |
74 | - %th Project name | |
75 | - %th Max access | |
76 | - %th.cred Danger Zone! | |
77 | - - @team.projects.each do |project| | |
78 | - %tr.project | |
79 | - %td | |
80 | - = link_to project.name_with_namespace, [:admin, project] | |
81 | - %td | |
82 | - %span= @team.human_max_project_access(project) | |
83 | - %td.bgred | |
84 | - = link_to 'Edit', edit_admin_team_project_path(@team, project), class: "btn small" | |
85 | - | |
86 | - = link_to 'Relegate', admin_team_project_path(@team, project), confirm: 'Remove project from team. Are you sure?', method: :delete, class: "btn danger small" | |
87 | - %tr | |
88 | - %td | |
89 | - %td | |
90 | - %td= link_to 'Add projects', new_admin_team_project_path(@team), class: "btn primary", id: :assign_projects_to_team | |
68 | + %legend | |
69 | + Projects (#{@team.projects.count}) | |
70 | + %span= link_to 'Add projects', new_admin_team_project_path(@team), class: "btn success small right", id: :assign_projects_to_team | |
71 | + - if @team.projects.any? | |
72 | + %table#projects_list | |
73 | + %thead | |
74 | + %tr | |
75 | + %th Project name | |
76 | + %th Max access | |
77 | + %th.cred.span3 Danger Zone! | |
78 | + - @team.projects.each do |project| | |
79 | + %tr.project | |
80 | + %td | |
81 | + = link_to project.name_with_namespace, [:admin, project] | |
82 | + %td | |
83 | + %span= @team.human_max_project_access(project) | |
84 | + %td.bgred | |
85 | + = link_to 'Edit', edit_admin_team_project_path(@team, project), class: "btn small" | |
86 | + | |
87 | + = link_to 'Relegate', admin_team_project_path(@team, project), confirm: 'Remove project from team. Are you sure?', method: :delete, class: "btn danger small" | |
91 | 88 | |
92 | 89 | :javascript |
93 | 90 | $(function(){ | ... | ... |
app/views/dashboard/_teams.html.haml
... | ... | @@ -2,7 +2,7 @@ |
2 | 2 | %h5.title |
3 | 3 | My Teams |
4 | 4 | %small |
5 | - (#{teams.count}) | |
5 | + (#{@teams.count}) | |
6 | 6 | %span.right |
7 | 7 | = link_to new_team_path, class: "btn very_small info" do |
8 | 8 | %i.icon-plus |
... | ... | @@ -12,7 +12,7 @@ |
12 | 12 | %i.icon-user |
13 | 13 | All Teams |
14 | 14 | %ul.well-list |
15 | - - teams.each do |team| | |
15 | + - @teams.each do |team| | |
16 | 16 | %li |
17 | 17 | = link_to team_path(id: team.path), class: dom_class(team) do |
18 | 18 | %strong.well-title= truncate(team.name, length: 35) |
... | ... | @@ -20,4 +20,7 @@ |
20 | 20 | → |
21 | 21 | %span.last_activity |
22 | 22 | %strong Projects: |
23 | - %span= current_user.authorized_projects.in_team(team).count | |
23 | + %span= team.projects.count | |
24 | + %span.last_activity | |
25 | + %strong Members: | |
26 | + %span= team.members.count | ... | ... |
app/views/layouts/_head_panel.html.haml
... | ... | @@ -8,6 +8,9 @@ |
8 | 8 | %span.separator |
9 | 9 | %h1.project_name= title |
10 | 10 | %ul.nav |
11 | + %li | |
12 | + = link_to teams_path, title: "Teams of users", class: 'has_bottom_tooltip', 'data-original-title' => 'Teams list' do | |
13 | + %i.icon-globe | |
11 | 14 | - if current_user.is_admin? |
12 | 15 | %li |
13 | 16 | = link_to admin_root_path, title: "Admin area", class: 'has_bottom_tooltip', 'data-original-title' => 'Admin area' do | ... | ... |
app/views/layouts/user_team.html.haml
1 | 1 | !!! 5 |
2 | 2 | %html{ lang: "en"} |
3 | - = render "layouts/head", title: "#{@user_team.name}" | |
3 | + = render "layouts/head", title: "#{@team.name}" | |
4 | 4 | %body{class: "#{app_theme} application"} |
5 | 5 | = render "layouts/flash" |
6 | - = render "layouts/head_panel", title: "#{@user_team.name}" | |
6 | + = render "layouts/head_panel", title: "#{@team.name}" | |
7 | 7 | .container |
8 | 8 | %ul.main_menu |
9 | 9 | = nav_link(path: 'teams#show', html_options: {class: 'home'}) do |
10 | - = link_to "Home", team_path(@user_team), title: "Home" | |
10 | + = link_to "Home", team_path(@team), title: "Home" | |
11 | 11 | = nav_link(path: 'teams#issues') do |
12 | - = link_to issues_team_path(@user_team) do | |
12 | + = link_to issues_team_path(@team) do | |
13 | 13 | Issues |
14 | - %span.count= Issue.opened.of_user_team(@user_team).count | |
14 | + %span.count= Issue.opened.of_user_team(@team).count | |
15 | 15 | = nav_link(path: 'teams#merge_requests') do |
16 | - = link_to merge_requests_team_path(@user_team) do | |
16 | + = link_to merge_requests_team_path(@team) do | |
17 | 17 | Merge Requests |
18 | - %span.count= MergeRequest.opened.of_user_team(@user_team).count | |
18 | + %span.count= MergeRequest.opened.of_user_team(@team).count | |
19 | 19 | = nav_link(path: 'teams#search') do |
20 | - = link_to "Search", search_team_path(@user_team) | |
20 | + = link_to "Search", search_team_path(@team) | |
21 | 21 | |
22 | 22 | .content= yield | ... | ... |
app/views/teams/_team_head.html.haml
1 | 1 | %ul.nav.nav-tabs |
2 | 2 | = nav_link(path: 'teams#show') do |
3 | - = link_to team_path(@user_team), class: "activities-tab tab" do | |
3 | + = link_to team_path(@team), class: "activities-tab tab" do | |
4 | 4 | %i.icon-home |
5 | 5 | Show |
6 | 6 | = nav_link(controller: [:members]) do |
7 | - = link_to team_members_path(@user_team), class: "team-tab tab" do | |
7 | + = link_to team_members_path(@team), class: "team-tab tab" do | |
8 | 8 | %i.icon-user |
9 | 9 | Members |
10 | 10 | = nav_link(controller: [:projects]) do |
11 | - = link_to team_projects_path(@user_team), class: "team-tab tab" do | |
11 | + = link_to team_projects_path(@team), class: "team-tab tab" do | |
12 | 12 | %i.icon-briefcase |
13 | 13 | Projects |
14 | 14 | |
15 | - - if can? current_user, :manage_user_team, @user_team | |
15 | + - if can? current_user, :admin_user_team, @team | |
16 | 16 | = nav_link(path: 'teams#edit', html_options: {class: 'right'}) do |
17 | - = link_to edit_team_path(@user_team), class: "stat-tab tab " do | |
17 | + = link_to edit_team_path(@team), class: "stat-tab tab " do | |
18 | 18 | %i.icon-edit |
19 | - Edit | |
19 | + Edit Team | ... | ... |
app/views/teams/edit.html.haml
1 | 1 | = render "team_head" |
2 | 2 | |
3 | -%h3.page_title= "Edit Team #{@user_team.name}" | |
3 | +%h3.page_title= "Edit Team #{@team.name}" | |
4 | 4 | %hr |
5 | -= form_for @user_team, url: teams_path do |f| | |
6 | - - if @user_team.errors.any? | |
5 | += form_for @team, url: teams_path do |f| | |
6 | + - if @team.errors.any? | |
7 | 7 | .alert-message.block-message.error |
8 | - %span= @user_team.errors.full_messages.first | |
8 | + %span= @team.errors.full_messages.first | |
9 | 9 | .clearfix |
10 | 10 | = f.label :name do |
11 | 11 | Team name is |
... | ... | @@ -21,12 +21,4 @@ |
21 | 21 | .input.span3.center |
22 | 22 | = f.submit 'Save team changes', class: "btn primary" |
23 | 23 | .input.span3.center |
24 | - = link_to 'Delete team', team_path(@user_team), method: :delete, confirm: "You are shure?", class: "btn danger" | |
25 | - %hr | |
26 | - .padded | |
27 | - %ul | |
28 | - %li Team is kind of directory for several projects | |
29 | - %li All created teams are private | |
30 | - %li People within a team see only projects they have access to | |
31 | - %li All projects of team will be stored in team directory | |
32 | - %li You will be able to move existing projects into team | |
24 | + = link_to 'Delete team', team_path(@team), method: :delete, confirm: "You are shure?", class: "btn danger" | ... | ... |
app/views/teams/index.html.haml
... | ... | @@ -3,7 +3,7 @@ |
3 | 3 | %small |
4 | 4 | list of all teams |
5 | 5 | |
6 | - = link_to 'New Team', new_team_path, class: "btn small right" | |
6 | + = link_to 'New Team', new_team_path, class: "btn success small right" | |
7 | 7 | %br |
8 | 8 | |
9 | 9 | = form_tag search_teams_path, method: :get, class: 'form-inline' do |
... | ... | @@ -32,6 +32,7 @@ |
32 | 32 | %td= link_to team.owner.name, team_member_path(team, team.owner) |
33 | 33 | %td |
34 | 34 | - if current_user.can?(:manage_user_team, team) |
35 | - - if team.owner == current_user | |
35 | + - if current_user.can?(:admin_user_team, team) | |
36 | 36 | = link_to "Destroy", team_path(team), method: :delete, confirm: "You are shure?", class: "danger btn small right" |
37 | + | |
37 | 38 | = link_to "Edit", edit_team_path(team), class: "btn small right" | ... | ... |
app/views/teams/members/_form.html.haml
1 | -%h3.page_title | |
2 | - = "New Team member(s)" | |
3 | -%hr | |
4 | -= form_for @team_member, as: :team_member, url: project_team_members_path(@project, @team_member) do |f| | |
5 | - -if @team_member.errors.any? | |
1 | += form_tag admin_team_member_path(@team, @member), method: :put do | |
2 | + -if @member.errors.any? | |
6 | 3 | .alert-message.block-message.error |
7 | 4 | %ul |
8 | - - @team_member.errors.full_messages.each do |msg| | |
5 | + - @member.errors.full_messages.each do |msg| | |
9 | 6 | %li= msg |
10 | 7 | |
11 | - %h6 1. Choose people you want in the team | |
12 | 8 | .clearfix |
13 | - = f.label :user_ids, "People" | |
14 | - .input= select_tag(:user_ids, options_from_collection_for_select(User.active.not_in_project(@project).alphabetically, :id, :name), {data: {placeholder: "Select users"}, class: "chosen xxlarge", multiple: true}) | |
15 | - | |
16 | - %h6 2. Set access level for them | |
9 | + %label Default access for Team projects: | |
10 | + .input | |
11 | + = select_tag :default_project_access, options_for_select(UserTeam.access_roles, @team.default_projects_access(@member)), class: "project-access-select chosen span3" | |
17 | 12 | .clearfix |
18 | - = f.label :project_access, "Project Access" | |
19 | - .input= select_tag :project_access, options_for_select(Project.access_options, @team_member.project_access), class: "project-access-select chosen" | |
13 | + %label Team admin? | |
14 | + .input | |
15 | + = check_box_tag :group_admin, true, @team.admin?(@member) | |
20 | 16 | |
17 | + %br | |
21 | 18 | .actions |
22 | - = f.submit 'Save', class: "btn save-btn" | |
23 | - = link_to "Cancel", project_team_index_path(@project), class: "btn cancel-btn" | |
19 | + = submit_tag 'Save', class: "btn primary" | |
20 | + = link_to 'Cancel', :back, class: "btn" | ... | ... |
app/views/teams/members/_show.html.haml
1 | 1 | - user = member.user |
2 | -- allow_admin = can? current_user, :manage_user_team, @user_team | |
2 | +- allow_admin = can? current_user, :manage_user_team, @team | |
3 | 3 | %li{id: dom_id(member), class: "team_member_row user_#{user.id}"} |
4 | 4 | .row |
5 | 5 | .span5 |
6 | - = link_to team_member_path(@user_team, user), title: user.name, class: "dark" do | |
6 | + = link_to team_member_path(@team, user), title: user.name, class: "dark" do | |
7 | 7 | = image_tag gravatar_icon(user.email, 40), class: "avatar s32" |
8 | - = link_to team_member_path(@user_team, user), title: user.name, class: "dark" do | |
8 | + = link_to team_member_path(@team, user), title: user.name, class: "dark" do | |
9 | 9 | %strong= truncate(user.name, lenght: 40) |
10 | 10 | %br |
11 | 11 | %small.cgray= user.email |
... | ... | @@ -13,8 +13,8 @@ |
13 | 13 | .span6.right |
14 | 14 | - if allow_admin |
15 | 15 | .left.span2 |
16 | - = form_for(member, as: :team_member, url: team_member_path(@user_team, user)) do |f| | |
17 | - = f.select :permission, options_for_select(UsersProject.access_roles, @user_team.default_projects_access(user)), {}, class: "medium project-access-select span2" | |
16 | + = form_for(member, as: :team_member, url: team_member_path(@team, user)) do |f| | |
17 | + = f.select :permission, options_for_select(UsersProject.access_roles, @team.default_projects_access(user)), {}, class: "medium project-access-select span2" | |
18 | 18 | .left.span2 |
19 | 19 | %span |
20 | 20 | Admin access |
... | ... | @@ -22,10 +22,10 @@ |
22 | 22 | .right |
23 | 23 | - if current_user == user |
24 | 24 | %span.btn.disabled This is you! |
25 | - - if @user_team.owner == user | |
25 | + - if @team.owner == user | |
26 | 26 | %span.btn.disabled.success Owner |
27 | 27 | - elsif user.blocked |
28 | 28 | %span.btn.disabled.blocked Blocked |
29 | 29 | - elsif allow_admin |
30 | - = link_to team_member_path(@user_team, user), confirm: remove_from_user_team_message(@user_team, user), method: :delete, class: "very_small btn danger" do | |
30 | + = link_to team_member_path(@team, user), confirm: remove_from_user_team_message(@team, user), method: :delete, class: "very_small btn danger" do | |
31 | 31 | %i.icon-minus.icon-white | ... | ... |
app/views/teams/members/_team.html.haml
app/views/teams/members/edit.html.haml
1 | -%h1 Teams::Members#edit | |
2 | -%p Find me in app/views/teams/members/edit.html.haml | |
3 | 1 | \ No newline at end of file |
2 | += render "teams/team_head" | |
3 | + | |
4 | +%h3 | |
5 | + Edit access #{@member.name} in #{@team.name} team | |
6 | + | |
7 | +%hr | |
8 | +%table.zebra-striped | |
9 | + %tr | |
10 | + %td User: | |
11 | + %td= @member.name | |
12 | + %tr | |
13 | + %td Team: | |
14 | + %td= @team.name | |
15 | + %tr | |
16 | + %td Since: | |
17 | + %td= member_since(@team, @member).stamp("Nov 11, 2010") | |
18 | + | |
19 | += render 'form' | ... | ... |
app/views/teams/members/import.html.haml
... | ... | @@ -1,17 +0,0 @@ |
1 | -= render "projects/project_head" | |
2 | - | |
3 | -%h3.page_title | |
4 | - = "Import team from another project" | |
5 | -%hr | |
6 | -%p.slead | |
7 | - Read more about team import #{link_to "here", '#', class: 'vlink'}. | |
8 | -= form_tag apply_import_project_team_members_path(@project), method: 'post' do | |
9 | - %p.slead Choose project you want to use as team source: | |
10 | - .padded | |
11 | - = label_tag :source_project_id, "Project" | |
12 | - .input= select_tag(:source_project_id, options_from_collection_for_select(current_user.authorized_projects, :id, :name_with_namespace), prompt: "Select project", class: "chosen xxlarge", required: true) | |
13 | - | |
14 | - .actions | |
15 | - = submit_tag 'Import', class: "btn save-btn" | |
16 | - = link_to "Cancel", project_team_index_path(@project), class: "btn cancel-btn" | |
17 | - |
app/views/teams/members/index.html.haml
1 | 1 | = render "teams/team_head" |
2 | + | |
2 | 3 | %h3.page_title |
3 | 4 | Team Members |
4 | 5 | (#{@members.count}) |
... | ... | @@ -6,13 +7,13 @@ |
6 | 7 | Read more about project permissions |
7 | 8 | %strong= link_to "here", help_permissions_path, class: "vlink" |
8 | 9 | |
9 | - - if can? current_user, :manage_user_team, @user_team | |
10 | + - if can? current_user, :manage_user_team, @team | |
10 | 11 | %span.right |
11 | - = link_to new_team_member_path(@user_team), class: "btn success small grouped", title: "New Team Member" do | |
12 | + = link_to new_team_member_path(@team), class: "btn success small grouped", title: "New Team Member" do | |
12 | 13 | New Team Member |
13 | 14 | %hr |
14 | 15 | |
15 | 16 | |
16 | 17 | .clearfix |
17 | 18 | %div.team-table |
18 | - = render partial: "teams/members/team", locals: {project: @user_team} | |
19 | + = render partial: "teams/members/team", locals: {project: @team} | ... | ... |
app/views/teams/members/new.html.haml
1 | -= render "projects/project_head" | |
2 | -= render "team_members/form" | |
1 | += render "teams/team_head" | |
2 | + | |
3 | +%h3.page_title | |
4 | + Team: #{@team.name} | |
5 | + | |
6 | +%fieldset | |
7 | + %legend Members (#{@team.members.count}) | |
8 | + = form_tag team_members_path(@team), id: "team_members", class: "bulk_import", method: :post do | |
9 | + %table#members_list | |
10 | + %thead | |
11 | + %tr | |
12 | + %th User name | |
13 | + %th Default project access | |
14 | + %th Team access | |
15 | + %th | |
16 | + - @team.members.each do |member| | |
17 | + %tr.member | |
18 | + %td | |
19 | + = member.name | |
20 | + %small= "(#{member.email})" | |
21 | + %td= @team.human_default_projects_access(member) | |
22 | + %td= @team.admin?(member) ? "Admin" : "Member" | |
23 | + %td | |
24 | + %tr | |
25 | + %td= select_tag :user_ids, options_from_collection_for_select(@users , :id, :name_with_email), multiple: true, data: {placeholder: 'Select users'}, class: 'chosen span5' | |
26 | + %td= select_tag :default_project_access, options_for_select(Project.access_options), {class: "project-access-select chosen span3" } | |
27 | + %td | |
28 | + %span= check_box_tag :group_admin | |
29 | + %span Admin? | |
30 | + %td= submit_tag 'Add', class: "btn primary", id: :add_members_to_team | ... | ... |
app/views/teams/members/show.html.haml
app/views/teams/merge_requests.html.haml
app/views/teams/new.html.haml
... | ... | @@ -14,8 +14,6 @@ |
14 | 14 | %hr |
15 | 15 | .padded |
16 | 16 | %ul |
17 | - %li Team is kind of directory for several projects | |
18 | - %li All created teams are private | |
17 | + %li All created teams are public (users can view who enter into team and which project are assigned for this team) | |
19 | 18 | %li People within a team see only projects they have access to |
20 | - %li All projects of team will be stored in team directory | |
21 | - %li You will be able to move existing projects into team | |
19 | + %li You will be able to assign existing projects for team | ... | ... |
... | ... | @@ -0,0 +1,16 @@ |
1 | += form_tag team_project_path(@team, @project), method: :put do | |
2 | + -if @project.errors.any? | |
3 | + .alert-message.block-message.error | |
4 | + %ul | |
5 | + - @project.errors.full_messages.each do |msg| | |
6 | + %li= msg | |
7 | + | |
8 | + .clearfix | |
9 | + %label Max access for Team members: | |
10 | + .input | |
11 | + = select_tag :greatest_project_access, options_for_select(UserTeam.access_roles, @team.max_project_access(@project)), class: "project-access-select chosen span3" | |
12 | + | |
13 | + %br | |
14 | + .actions | |
15 | + = submit_tag 'Save', class: "btn primary" | |
16 | + = link_to 'Cancel', :back, class: "btn" | ... | ... |
app/views/teams/projects/edit.html.haml
1 | 1 | = render "teams/team_head" |
2 | 2 | |
3 | -%h1 Teams::Projects#edit | |
4 | -%p Find me in app/views/teams/projects/edit.html.haml | |
3 | +%h3 | |
4 | + Edit max access in #{@project.name} for #{@team.name} team | |
5 | + | |
6 | +%hr | |
7 | +%table.zebra-striped | |
8 | + %tr | |
9 | + %td Project: | |
10 | + %td= @project.name | |
11 | + %tr | |
12 | + %td Team: | |
13 | + %td= @team.name | |
14 | + %tr | |
15 | + %td Since: | |
16 | + %td= assigned_since(@team, @project).stamp("Nov 11, 2010") | |
17 | + | |
18 | += render 'form' | ... | ... |
app/views/teams/projects/index.html.haml
1 | 1 | = render "teams/team_head" |
2 | 2 | |
3 | -%fieldset | |
4 | - %legend Projects (#{@user_team.projects.count}) | |
5 | - = form_tag delegate_projects_team_path(@user_team), id: "team_projects", class: "bulk_import", method: :post do | |
6 | - %table | |
7 | - %thead | |
8 | - %tr | |
9 | - %th Project name | |
10 | - %th Max access | |
11 | - %th | |
12 | - - @user_team.projects.each do |project| | |
13 | - %tr.project | |
14 | - %td | |
15 | - = link_to project.name_with_namespace, project | |
16 | - %td | |
17 | - %span= @user_team.human_max_project_access(project) | |
18 | - -# if current_user.can?(:manage_user_team, @user_team) | |
19 | - - relation = project.user_team_project_relationships.find_by_user_team_id(@user_team) | |
20 | - = form_for(relation, as: :project, url: team_project_path(@user_team, project)) do |f| | |
21 | - = f.select :greatest_access, options_for_select(UsersProject.access_roles, @user_team.max_project_access(project)), {}, class: "medium project-access-select span2" | |
3 | +%h3.page_title | |
4 | + Assigned projects (#{@team.projects.count}) | |
5 | + %small | |
6 | + Read more about project permissions | |
7 | + %strong= link_to "here", help_permissions_path, class: "vlink" | |
22 | 8 | |
23 | - - if current_user.can?(:admin_user_team, @user_team) | |
24 | - %td.bgred | |
25 | - -#= link_to 'Edit max access', edit_project_team_path(@user_team, project), class: "btn small" | |
26 | - = link_to 'Relegate', relegate_project_team_path(@user_team, project_id: project.id), confirm: 'Remove project from team and move to global namespace. Are you sure?', method: :delete, class: "btn danger small" | |
27 | - - else | |
28 | - %td | |
9 | + - if current_user.can?(:manage_user_team, @team) && @avaliable_projects.any? | |
10 | + %span.right | |
11 | + = link_to new_team_project_path(@team), class: "btn success small grouped", title: "New Team Member" do | |
12 | + Assign project to Team | |
29 | 13 | |
30 | - - if @avaliable_projects.any? | |
31 | - %tr | |
32 | - %td= select_tag :project_ids, options_from_collection_for_select(@avaliable_projects , :id, :name_with_namespace), multiple: true, data: {placeholder: 'Select projects'}, class: 'chosen span5' | |
33 | - %td= select_tag :greatest_project_access, options_for_select(Project.access_options), {class: "project-access-select chosen span3" } | |
34 | - %td= submit_tag 'Add', class: "btn primary" | |
14 | +%hr | |
15 | + | |
16 | +%table | |
17 | + %thead | |
18 | + %tr | |
19 | + %th Project name | |
20 | + %th Max access | |
21 | + - if current_user.can?(:admin_user_team, @team) | |
22 | + %th.span3 | |
23 | + | |
24 | + - @team.projects.each do |project| | |
25 | + %tr.project | |
26 | + %td | |
27 | + = link_to project.name_with_namespace, project_path(project) | |
28 | + %td | |
29 | + %span= @team.human_max_project_access(project) | |
30 | + | |
31 | + - if current_user.can?(:admin_user_team, @team) | |
32 | + %td.bgred | |
33 | + = link_to 'Edit max access', edit_team_project_path(@team, project), class: "btn small" | |
34 | + = link_to 'Relegate', team_project_path(@team, project), confirm: 'Remove project from team and move to global namespace. Are you sure?', method: :delete, class: "btn danger small" | ... | ... |
app/views/teams/projects/new.html.haml
1 | 1 | = render "teams/team_head" |
2 | 2 | |
3 | -%h1 Teams::Projects#new | |
4 | -%p Find me in app/views/teams/projects/new.html.haml | |
3 | +%h3.page_title | |
4 | + Team: #{@team.name} | |
5 | + | |
6 | +%fieldset | |
7 | + %legend Projects (#{@team.projects.count}) | |
8 | + = form_tag team_projects_path(@team), id: "assign_projects", class: "bulk_import", method: :post do | |
9 | + %table#projects_list | |
10 | + %thead | |
11 | + %tr | |
12 | + %th Project name | |
13 | + %th Max access | |
14 | + %th | |
15 | + - @team.projects.each do |project| | |
16 | + %tr.project | |
17 | + %td | |
18 | + = link_to project.name_with_namespace, team_project_path(@team, project) | |
19 | + %td | |
20 | + %span= @team.human_max_project_access(project) | |
21 | + %td | |
22 | + %tr | |
23 | + %td= select_tag :project_ids, options_from_collection_for_select(@avaliable_projects , :id, :name_with_namespace), multiple: true, data: {placeholder: 'Select projects'}, class: 'chosen span5' | |
24 | + %td= select_tag :greatest_project_access, options_for_select(UserTeam.access_roles), {class: "project-access-select chosen span3" } | |
25 | + %td= submit_tag 'Add', class: "btn primary", id: :assign_projects_to_team | ... | ... |
app/views/teams/projects/show.html.haml
app/views/teams/search.html.haml