@@ -0,0 +1,1 | |||
|
1 | $('#users').html('<%= escape_javascript(render_principals_for_new_group_users(@group)) %>'); |
@@ -0,0 +1,1 | |||
|
1 | $('#principals_for_new_member').html('<%= escape_javascript(render_principals_for_new_members(@project)) %>'); |
@@ -1,140 +1,141 | |||
|
1 | 1 | # Redmine - project management software |
|
2 | 2 | # Copyright (C) 2006-2013 Jean-Philippe Lang |
|
3 | 3 | # |
|
4 | 4 | # This program is free software; you can redistribute it and/or |
|
5 | 5 | # modify it under the terms of the GNU General Public License |
|
6 | 6 | # as published by the Free Software Foundation; either version 2 |
|
7 | 7 | # of the License, or (at your option) any later version. |
|
8 | 8 | # |
|
9 | 9 | # This program is distributed in the hope that it will be useful, |
|
10 | 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 | 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 | 12 | # GNU General Public License for more details. |
|
13 | 13 | # |
|
14 | 14 | # You should have received a copy of the GNU General Public License |
|
15 | 15 | # along with this program; if not, write to the Free Software |
|
16 | 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
17 | 17 | |
|
18 | 18 | class GroupsController < ApplicationController |
|
19 | 19 | layout 'admin' |
|
20 | 20 | |
|
21 | 21 | before_filter :require_admin |
|
22 | 22 | before_filter :find_group, :except => [:index, :new, :create] |
|
23 | 23 | accept_api_auth :index, :show, :create, :update, :destroy, :add_users, :remove_user |
|
24 | 24 | |
|
25 | 25 | helper :custom_fields |
|
26 | 26 | |
|
27 | 27 | def index |
|
28 | 28 | @groups = Group.sorted.all |
|
29 | 29 | |
|
30 | 30 | respond_to do |format| |
|
31 | 31 | format.html |
|
32 | 32 | format.api |
|
33 | 33 | end |
|
34 | 34 | end |
|
35 | 35 | |
|
36 | 36 | def show |
|
37 | 37 | respond_to do |format| |
|
38 | 38 | format.html |
|
39 | 39 | format.api |
|
40 | 40 | end |
|
41 | 41 | end |
|
42 | 42 | |
|
43 | 43 | def new |
|
44 | 44 | @group = Group.new |
|
45 | 45 | end |
|
46 | 46 | |
|
47 | 47 | def create |
|
48 | 48 | @group = Group.new |
|
49 | 49 | @group.safe_attributes = params[:group] |
|
50 | 50 | |
|
51 | 51 | respond_to do |format| |
|
52 | 52 | if @group.save |
|
53 | 53 | format.html { |
|
54 | 54 | flash[:notice] = l(:notice_successful_create) |
|
55 | 55 | redirect_to(params[:continue] ? new_group_path : groups_path) |
|
56 | 56 | } |
|
57 | 57 | format.api { render :action => 'show', :status => :created, :location => group_url(@group) } |
|
58 | 58 | else |
|
59 | 59 | format.html { render :action => "new" } |
|
60 | 60 | format.api { render_validation_errors(@group) } |
|
61 | 61 | end |
|
62 | 62 | end |
|
63 | 63 | end |
|
64 | 64 | |
|
65 | 65 | def edit |
|
66 | 66 | end |
|
67 | 67 | |
|
68 | 68 | def update |
|
69 | 69 | @group.safe_attributes = params[:group] |
|
70 | 70 | |
|
71 | 71 | respond_to do |format| |
|
72 | 72 | if @group.save |
|
73 | 73 | flash[:notice] = l(:notice_successful_update) |
|
74 | 74 | format.html { redirect_to(groups_path) } |
|
75 | 75 | format.api { render_api_ok } |
|
76 | 76 | else |
|
77 | 77 | format.html { render :action => "edit" } |
|
78 | 78 | format.api { render_validation_errors(@group) } |
|
79 | 79 | end |
|
80 | 80 | end |
|
81 | 81 | end |
|
82 | 82 | |
|
83 | 83 | def destroy |
|
84 | 84 | @group.destroy |
|
85 | 85 | |
|
86 | 86 | respond_to do |format| |
|
87 | 87 | format.html { redirect_to(groups_path) } |
|
88 | 88 | format.api { render_api_ok } |
|
89 | 89 | end |
|
90 | 90 | end |
|
91 | 91 | |
|
92 | 92 | def add_users |
|
93 | 93 | @users = User.find_all_by_id(params[:user_id] || params[:user_ids]) |
|
94 | 94 | @group.users << @users if request.post? |
|
95 | 95 | respond_to do |format| |
|
96 | 96 | format.html { redirect_to edit_group_path(@group, :tab => 'users') } |
|
97 | 97 | format.js |
|
98 | 98 | format.api { render_api_ok } |
|
99 | 99 | end |
|
100 | 100 | end |
|
101 | 101 | |
|
102 | 102 | def remove_user |
|
103 | 103 | @group.users.delete(User.find(params[:user_id])) if request.delete? |
|
104 | 104 | respond_to do |format| |
|
105 | 105 | format.html { redirect_to edit_group_path(@group, :tab => 'users') } |
|
106 | 106 | format.js |
|
107 | 107 | format.api { render_api_ok } |
|
108 | 108 | end |
|
109 | 109 | end |
|
110 | 110 | |
|
111 | 111 | def autocomplete_for_user |
|
112 | @users = User.active.not_in_group(@group).like(params[:q]).all(:limit => 100) | |
|
113 | render :layout => false | |
|
112 | respond_to do |format| | |
|
113 | format.js | |
|
114 | end | |
|
114 | 115 | end |
|
115 | 116 | |
|
116 | 117 | def edit_membership |
|
117 | 118 | @membership = Member.edit_membership(params[:membership_id], params[:membership], @group) |
|
118 | 119 | @membership.save if request.post? |
|
119 | 120 | respond_to do |format| |
|
120 | 121 | format.html { redirect_to edit_group_path(@group, :tab => 'memberships') } |
|
121 | 122 | format.js |
|
122 | 123 | end |
|
123 | 124 | end |
|
124 | 125 | |
|
125 | 126 | def destroy_membership |
|
126 | 127 | Member.find(params[:membership_id]).destroy if request.post? |
|
127 | 128 | respond_to do |format| |
|
128 | 129 | format.html { redirect_to edit_group_path(@group, :tab => 'memberships') } |
|
129 | 130 | format.js |
|
130 | 131 | end |
|
131 | 132 | end |
|
132 | 133 | |
|
133 | 134 | private |
|
134 | 135 | |
|
135 | 136 | def find_group |
|
136 | 137 | @group = Group.find(params[:id]) |
|
137 | 138 | rescue ActiveRecord::RecordNotFound |
|
138 | 139 | render_404 |
|
139 | 140 | end |
|
140 | 141 | end |
@@ -1,124 +1,125 | |||
|
1 | 1 | # Redmine - project management software |
|
2 | 2 | # Copyright (C) 2006-2013 Jean-Philippe Lang |
|
3 | 3 | # |
|
4 | 4 | # This program is free software; you can redistribute it and/or |
|
5 | 5 | # modify it under the terms of the GNU General Public License |
|
6 | 6 | # as published by the Free Software Foundation; either version 2 |
|
7 | 7 | # of the License, or (at your option) any later version. |
|
8 | 8 | # |
|
9 | 9 | # This program is distributed in the hope that it will be useful, |
|
10 | 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 | 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 | 12 | # GNU General Public License for more details. |
|
13 | 13 | # |
|
14 | 14 | # You should have received a copy of the GNU General Public License |
|
15 | 15 | # along with this program; if not, write to the Free Software |
|
16 | 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
17 | 17 | |
|
18 | 18 | class MembersController < ApplicationController |
|
19 | 19 | model_object Member |
|
20 | 20 | before_filter :find_model_object, :except => [:index, :create, :autocomplete] |
|
21 | 21 | before_filter :find_project_from_association, :except => [:index, :create, :autocomplete] |
|
22 | 22 | before_filter :find_project_by_project_id, :only => [:index, :create, :autocomplete] |
|
23 | 23 | before_filter :authorize |
|
24 | 24 | accept_api_auth :index, :show, :create, :update, :destroy |
|
25 | 25 | |
|
26 | 26 | def index |
|
27 | 27 | @offset, @limit = api_offset_and_limit |
|
28 | 28 | @member_count = @project.member_principals.count |
|
29 | 29 | @member_pages = Paginator.new @member_count, @limit, params['page'] |
|
30 | 30 | @offset ||= @member_pages.offset |
|
31 | 31 | @members = @project.member_principals.all( |
|
32 | 32 | :order => "#{Member.table_name}.id", |
|
33 | 33 | :limit => @limit, |
|
34 | 34 | :offset => @offset |
|
35 | 35 | ) |
|
36 | 36 | |
|
37 | 37 | respond_to do |format| |
|
38 | 38 | format.html { head 406 } |
|
39 | 39 | format.api |
|
40 | 40 | end |
|
41 | 41 | end |
|
42 | 42 | |
|
43 | 43 | def show |
|
44 | 44 | respond_to do |format| |
|
45 | 45 | format.html { head 406 } |
|
46 | 46 | format.api |
|
47 | 47 | end |
|
48 | 48 | end |
|
49 | 49 | |
|
50 | 50 | def create |
|
51 | 51 | members = [] |
|
52 | 52 | if params[:membership] |
|
53 | 53 | if params[:membership][:user_ids] |
|
54 | 54 | attrs = params[:membership].dup |
|
55 | 55 | user_ids = attrs.delete(:user_ids) |
|
56 | 56 | user_ids.each do |user_id| |
|
57 | 57 | members << Member.new(:role_ids => params[:membership][:role_ids], :user_id => user_id) |
|
58 | 58 | end |
|
59 | 59 | else |
|
60 | 60 | members << Member.new(:role_ids => params[:membership][:role_ids], :user_id => params[:membership][:user_id]) |
|
61 | 61 | end |
|
62 | 62 | @project.members << members |
|
63 | 63 | end |
|
64 | 64 | |
|
65 | 65 | respond_to do |format| |
|
66 | 66 | format.html { redirect_to_settings_in_projects } |
|
67 | 67 | format.js { @members = members } |
|
68 | 68 | format.api { |
|
69 | 69 | @member = members.first |
|
70 | 70 | if @member.valid? |
|
71 | 71 | render :action => 'show', :status => :created, :location => membership_url(@member) |
|
72 | 72 | else |
|
73 | 73 | render_validation_errors(@member) |
|
74 | 74 | end |
|
75 | 75 | } |
|
76 | 76 | end |
|
77 | 77 | end |
|
78 | 78 | |
|
79 | 79 | def update |
|
80 | 80 | if params[:membership] |
|
81 | 81 | @member.role_ids = params[:membership][:role_ids] |
|
82 | 82 | end |
|
83 | 83 | saved = @member.save |
|
84 | 84 | respond_to do |format| |
|
85 | 85 | format.html { redirect_to_settings_in_projects } |
|
86 | 86 | format.js |
|
87 | 87 | format.api { |
|
88 | 88 | if saved |
|
89 | 89 | render_api_ok |
|
90 | 90 | else |
|
91 | 91 | render_validation_errors(@member) |
|
92 | 92 | end |
|
93 | 93 | } |
|
94 | 94 | end |
|
95 | 95 | end |
|
96 | 96 | |
|
97 | 97 | def destroy |
|
98 | 98 | if request.delete? && @member.deletable? |
|
99 | 99 | @member.destroy |
|
100 | 100 | end |
|
101 | 101 | respond_to do |format| |
|
102 | 102 | format.html { redirect_to_settings_in_projects } |
|
103 | 103 | format.js |
|
104 | 104 | format.api { |
|
105 | 105 | if @member.destroyed? |
|
106 | 106 | render_api_ok |
|
107 | 107 | else |
|
108 | 108 | head :unprocessable_entity |
|
109 | 109 | end |
|
110 | 110 | } |
|
111 | 111 | end |
|
112 | 112 | end |
|
113 | 113 | |
|
114 | 114 | def autocomplete |
|
115 | @principals = Principal.active.not_member_of(@project).like(params[:q]).all(:limit => 100) | |
|
116 | render :layout => false | |
|
115 | respond_to do |format| | |
|
116 | format.js | |
|
117 | end | |
|
117 | 118 | end |
|
118 | 119 | |
|
119 | 120 | private |
|
120 | 121 | |
|
121 | 122 | def redirect_to_settings_in_projects |
|
122 | 123 | redirect_to settings_project_path(@project, :tab => 'members') |
|
123 | 124 | end |
|
124 | 125 | end |
@@ -1,261 +1,262 | |||
|
1 | 1 | # Redmine - project management software |
|
2 | 2 | # Copyright (C) 2006-2013 Jean-Philippe Lang |
|
3 | 3 | # |
|
4 | 4 | # This program is free software; you can redistribute it and/or |
|
5 | 5 | # modify it under the terms of the GNU General Public License |
|
6 | 6 | # as published by the Free Software Foundation; either version 2 |
|
7 | 7 | # of the License, or (at your option) any later version. |
|
8 | 8 | # |
|
9 | 9 | # This program is distributed in the hope that it will be useful, |
|
10 | 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 | 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 | 12 | # GNU General Public License for more details. |
|
13 | 13 | # |
|
14 | 14 | # You should have received a copy of the GNU General Public License |
|
15 | 15 | # along with this program; if not, write to the Free Software |
|
16 | 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
17 | 17 | |
|
18 | 18 | class ProjectsController < ApplicationController |
|
19 | 19 | menu_item :overview |
|
20 | 20 | menu_item :roadmap, :only => :roadmap |
|
21 | 21 | menu_item :settings, :only => :settings |
|
22 | 22 | |
|
23 | 23 | before_filter :find_project, :except => [ :index, :list, :new, :create, :copy ] |
|
24 | 24 | before_filter :authorize, :except => [ :index, :list, :new, :create, :copy, :archive, :unarchive, :destroy] |
|
25 | 25 | before_filter :authorize_global, :only => [:new, :create] |
|
26 | 26 | before_filter :require_admin, :only => [ :copy, :archive, :unarchive, :destroy ] |
|
27 | 27 | accept_rss_auth :index |
|
28 | 28 | accept_api_auth :index, :show, :create, :update, :destroy |
|
29 | 29 | |
|
30 | 30 | after_filter :only => [:create, :edit, :update, :archive, :unarchive, :destroy] do |controller| |
|
31 | 31 | if controller.request.post? |
|
32 | 32 | controller.send :expire_action, :controller => 'welcome', :action => 'robots' |
|
33 | 33 | end |
|
34 | 34 | end |
|
35 | 35 | |
|
36 | 36 | helper :sort |
|
37 | 37 | include SortHelper |
|
38 | 38 | helper :custom_fields |
|
39 | 39 | include CustomFieldsHelper |
|
40 | 40 | helper :issues |
|
41 | 41 | helper :queries |
|
42 | 42 | include QueriesHelper |
|
43 | 43 | helper :repositories |
|
44 | 44 | include RepositoriesHelper |
|
45 | 45 | include ProjectsHelper |
|
46 | helper :members | |
|
46 | 47 | |
|
47 | 48 | # Lists visible projects |
|
48 | 49 | def index |
|
49 | 50 | respond_to do |format| |
|
50 | 51 | format.html { |
|
51 | 52 | scope = Project |
|
52 | 53 | unless params[:closed] |
|
53 | 54 | scope = scope.active |
|
54 | 55 | end |
|
55 | 56 | @projects = scope.visible.order('lft').all |
|
56 | 57 | } |
|
57 | 58 | format.api { |
|
58 | 59 | @offset, @limit = api_offset_and_limit |
|
59 | 60 | @project_count = Project.visible.count |
|
60 | 61 | @projects = Project.visible.offset(@offset).limit(@limit).order('lft').all |
|
61 | 62 | } |
|
62 | 63 | format.atom { |
|
63 | 64 | projects = Project.visible.order('created_on DESC').limit(Setting.feeds_limit.to_i).all |
|
64 | 65 | render_feed(projects, :title => "#{Setting.app_title}: #{l(:label_project_latest)}") |
|
65 | 66 | } |
|
66 | 67 | end |
|
67 | 68 | end |
|
68 | 69 | |
|
69 | 70 | def new |
|
70 | 71 | @issue_custom_fields = IssueCustomField.sorted.all |
|
71 | 72 | @trackers = Tracker.sorted.all |
|
72 | 73 | @project = Project.new |
|
73 | 74 | @project.safe_attributes = params[:project] |
|
74 | 75 | end |
|
75 | 76 | |
|
76 | 77 | def create |
|
77 | 78 | @issue_custom_fields = IssueCustomField.sorted.all |
|
78 | 79 | @trackers = Tracker.sorted.all |
|
79 | 80 | @project = Project.new |
|
80 | 81 | @project.safe_attributes = params[:project] |
|
81 | 82 | |
|
82 | 83 | if validate_parent_id && @project.save |
|
83 | 84 | @project.set_allowed_parent!(params[:project]['parent_id']) if params[:project].has_key?('parent_id') |
|
84 | 85 | # Add current user as a project member if he is not admin |
|
85 | 86 | unless User.current.admin? |
|
86 | 87 | r = Role.givable.find_by_id(Setting.new_project_user_role_id.to_i) || Role.givable.first |
|
87 | 88 | m = Member.new(:user => User.current, :roles => [r]) |
|
88 | 89 | @project.members << m |
|
89 | 90 | end |
|
90 | 91 | respond_to do |format| |
|
91 | 92 | format.html { |
|
92 | 93 | flash[:notice] = l(:notice_successful_create) |
|
93 | 94 | if params[:continue] |
|
94 | 95 | attrs = {:parent_id => @project.parent_id}.reject {|k,v| v.nil?} |
|
95 | 96 | redirect_to new_project_path(attrs) |
|
96 | 97 | else |
|
97 | 98 | redirect_to settings_project_path(@project) |
|
98 | 99 | end |
|
99 | 100 | } |
|
100 | 101 | format.api { render :action => 'show', :status => :created, :location => url_for(:controller => 'projects', :action => 'show', :id => @project.id) } |
|
101 | 102 | end |
|
102 | 103 | else |
|
103 | 104 | respond_to do |format| |
|
104 | 105 | format.html { render :action => 'new' } |
|
105 | 106 | format.api { render_validation_errors(@project) } |
|
106 | 107 | end |
|
107 | 108 | end |
|
108 | 109 | end |
|
109 | 110 | |
|
110 | 111 | def copy |
|
111 | 112 | @issue_custom_fields = IssueCustomField.sorted.all |
|
112 | 113 | @trackers = Tracker.sorted.all |
|
113 | 114 | @source_project = Project.find(params[:id]) |
|
114 | 115 | if request.get? |
|
115 | 116 | @project = Project.copy_from(@source_project) |
|
116 | 117 | @project.identifier = Project.next_identifier if Setting.sequential_project_identifiers? |
|
117 | 118 | else |
|
118 | 119 | Mailer.with_deliveries(params[:notifications] == '1') do |
|
119 | 120 | @project = Project.new |
|
120 | 121 | @project.safe_attributes = params[:project] |
|
121 | 122 | if validate_parent_id && @project.copy(@source_project, :only => params[:only]) |
|
122 | 123 | @project.set_allowed_parent!(params[:project]['parent_id']) if params[:project].has_key?('parent_id') |
|
123 | 124 | flash[:notice] = l(:notice_successful_create) |
|
124 | 125 | redirect_to settings_project_path(@project) |
|
125 | 126 | elsif !@project.new_record? |
|
126 | 127 | # Project was created |
|
127 | 128 | # But some objects were not copied due to validation failures |
|
128 | 129 | # (eg. issues from disabled trackers) |
|
129 | 130 | # TODO: inform about that |
|
130 | 131 | redirect_to settings_project_path(@project) |
|
131 | 132 | end |
|
132 | 133 | end |
|
133 | 134 | end |
|
134 | 135 | rescue ActiveRecord::RecordNotFound |
|
135 | 136 | # source_project not found |
|
136 | 137 | render_404 |
|
137 | 138 | end |
|
138 | 139 | |
|
139 | 140 | # Show @project |
|
140 | 141 | def show |
|
141 | 142 | if params[:jump] |
|
142 | 143 | # try to redirect to the requested menu item |
|
143 | 144 | redirect_to_project_menu_item(@project, params[:jump]) && return |
|
144 | 145 | end |
|
145 | 146 | |
|
146 | 147 | @users_by_role = @project.users_by_role |
|
147 | 148 | @subprojects = @project.children.visible.all |
|
148 | 149 | @news = @project.news.limit(5).includes(:author, :project).reorder("#{News.table_name}.created_on DESC").all |
|
149 | 150 | @trackers = @project.rolled_up_trackers |
|
150 | 151 | |
|
151 | 152 | cond = @project.project_condition(Setting.display_subprojects_issues?) |
|
152 | 153 | |
|
153 | 154 | @open_issues_by_tracker = Issue.visible.open.where(cond).count(:group => :tracker) |
|
154 | 155 | @total_issues_by_tracker = Issue.visible.where(cond).count(:group => :tracker) |
|
155 | 156 | |
|
156 | 157 | if User.current.allowed_to?(:view_time_entries, @project) |
|
157 | 158 | @total_hours = TimeEntry.visible.sum(:hours, :include => :project, :conditions => cond).to_f |
|
158 | 159 | end |
|
159 | 160 | |
|
160 | 161 | @key = User.current.rss_key |
|
161 | 162 | |
|
162 | 163 | respond_to do |format| |
|
163 | 164 | format.html |
|
164 | 165 | format.api |
|
165 | 166 | end |
|
166 | 167 | end |
|
167 | 168 | |
|
168 | 169 | def settings |
|
169 | 170 | @issue_custom_fields = IssueCustomField.sorted.all |
|
170 | 171 | @issue_category ||= IssueCategory.new |
|
171 | 172 | @member ||= @project.members.new |
|
172 | 173 | @trackers = Tracker.sorted.all |
|
173 | 174 | @wiki ||= @project.wiki |
|
174 | 175 | end |
|
175 | 176 | |
|
176 | 177 | def edit |
|
177 | 178 | end |
|
178 | 179 | |
|
179 | 180 | def update |
|
180 | 181 | @project.safe_attributes = params[:project] |
|
181 | 182 | if validate_parent_id && @project.save |
|
182 | 183 | @project.set_allowed_parent!(params[:project]['parent_id']) if params[:project].has_key?('parent_id') |
|
183 | 184 | respond_to do |format| |
|
184 | 185 | format.html { |
|
185 | 186 | flash[:notice] = l(:notice_successful_update) |
|
186 | 187 | redirect_to settings_project_path(@project) |
|
187 | 188 | } |
|
188 | 189 | format.api { render_api_ok } |
|
189 | 190 | end |
|
190 | 191 | else |
|
191 | 192 | respond_to do |format| |
|
192 | 193 | format.html { |
|
193 | 194 | settings |
|
194 | 195 | render :action => 'settings' |
|
195 | 196 | } |
|
196 | 197 | format.api { render_validation_errors(@project) } |
|
197 | 198 | end |
|
198 | 199 | end |
|
199 | 200 | end |
|
200 | 201 | |
|
201 | 202 | def modules |
|
202 | 203 | @project.enabled_module_names = params[:enabled_module_names] |
|
203 | 204 | flash[:notice] = l(:notice_successful_update) |
|
204 | 205 | redirect_to settings_project_path(@project, :tab => 'modules') |
|
205 | 206 | end |
|
206 | 207 | |
|
207 | 208 | def archive |
|
208 | 209 | if request.post? |
|
209 | 210 | unless @project.archive |
|
210 | 211 | flash[:error] = l(:error_can_not_archive_project) |
|
211 | 212 | end |
|
212 | 213 | end |
|
213 | 214 | redirect_to admin_projects_path(:status => params[:status]) |
|
214 | 215 | end |
|
215 | 216 | |
|
216 | 217 | def unarchive |
|
217 | 218 | @project.unarchive if request.post? && !@project.active? |
|
218 | 219 | redirect_to admin_projects_path(:status => params[:status]) |
|
219 | 220 | end |
|
220 | 221 | |
|
221 | 222 | def close |
|
222 | 223 | @project.close |
|
223 | 224 | redirect_to project_path(@project) |
|
224 | 225 | end |
|
225 | 226 | |
|
226 | 227 | def reopen |
|
227 | 228 | @project.reopen |
|
228 | 229 | redirect_to project_path(@project) |
|
229 | 230 | end |
|
230 | 231 | |
|
231 | 232 | # Delete @project |
|
232 | 233 | def destroy |
|
233 | 234 | @project_to_destroy = @project |
|
234 | 235 | if api_request? || params[:confirm] |
|
235 | 236 | @project_to_destroy.destroy |
|
236 | 237 | respond_to do |format| |
|
237 | 238 | format.html { redirect_to admin_projects_path } |
|
238 | 239 | format.api { render_api_ok } |
|
239 | 240 | end |
|
240 | 241 | end |
|
241 | 242 | # hide project in layout |
|
242 | 243 | @project = nil |
|
243 | 244 | end |
|
244 | 245 | |
|
245 | 246 | private |
|
246 | 247 | |
|
247 | 248 | # Validates parent_id param according to user's permissions |
|
248 | 249 | # TODO: move it to Project model in a validation that depends on User.current |
|
249 | 250 | def validate_parent_id |
|
250 | 251 | return true if User.current.admin? |
|
251 | 252 | parent_id = params[:project] && params[:project][:parent_id] |
|
252 | 253 | if parent_id || @project.new_record? |
|
253 | 254 | parent = parent_id.blank? ? nil : Project.find_by_id(parent_id.to_i) |
|
254 | 255 | unless @project.allowed_parents.include?(parent) |
|
255 | 256 | @project.errors.add :parent_id, :invalid |
|
256 | 257 | return false |
|
257 | 258 | end |
|
258 | 259 | end |
|
259 | 260 | true |
|
260 | 261 | end |
|
261 | 262 | end |
@@ -1,27 +1,42 | |||
|
1 | 1 | # encoding: utf-8 |
|
2 | 2 | # |
|
3 | 3 | # Redmine - project management software |
|
4 | 4 | # Copyright (C) 2006-2013 Jean-Philippe Lang |
|
5 | 5 | # |
|
6 | 6 | # This program is free software; you can redistribute it and/or |
|
7 | 7 | # modify it under the terms of the GNU General Public License |
|
8 | 8 | # as published by the Free Software Foundation; either version 2 |
|
9 | 9 | # of the License, or (at your option) any later version. |
|
10 | 10 | # |
|
11 | 11 | # This program is distributed in the hope that it will be useful, |
|
12 | 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
13 | 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
14 | 14 | # GNU General Public License for more details. |
|
15 | 15 | # |
|
16 | 16 | # You should have received a copy of the GNU General Public License |
|
17 | 17 | # along with this program; if not, write to the Free Software |
|
18 | 18 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
19 | 19 | |
|
20 | 20 | module GroupsHelper |
|
21 | 21 | def group_settings_tabs |
|
22 | 22 | tabs = [{:name => 'general', :partial => 'groups/general', :label => :label_general}, |
|
23 | 23 | {:name => 'users', :partial => 'groups/users', :label => :label_user_plural}, |
|
24 | 24 | {:name => 'memberships', :partial => 'groups/memberships', :label => :label_project_plural} |
|
25 | 25 | ] |
|
26 | 26 | end |
|
27 | ||
|
28 | def render_principals_for_new_group_users(group) | |
|
29 | scope = User.active.not_in_group(group).like(params[:q]) | |
|
30 | principal_count = scope.count | |
|
31 | principal_pages = Redmine::Pagination::Paginator.new principal_count, 100, params['page'] | |
|
32 | principals = scope.offset(principal_pages.offset).limit(principal_pages.per_page).all | |
|
33 | ||
|
34 | s = content_tag('div', principals_check_box_tags('user_ids[]', principals), :id => 'principals') | |
|
35 | ||
|
36 | links = pagination_links_full(principal_pages, principal_count, :per_page_links => false) {|text, parameters, options| | |
|
37 | link_to text, autocomplete_for_user_group_path(group, parameters.merge(:q => params[:q], :format => 'js')), :remote => true | |
|
38 | } | |
|
39 | ||
|
40 | s + content_tag('p', links, :class => 'pagination') | |
|
41 | end | |
|
27 | 42 | end |
@@ -1,21 +1,35 | |||
|
1 | 1 | # encoding: utf-8 |
|
2 | 2 | # |
|
3 | 3 | # Redmine - project management software |
|
4 | 4 | # Copyright (C) 2006-2013 Jean-Philippe Lang |
|
5 | 5 | # |
|
6 | 6 | # This program is free software; you can redistribute it and/or |
|
7 | 7 | # modify it under the terms of the GNU General Public License |
|
8 | 8 | # as published by the Free Software Foundation; either version 2 |
|
9 | 9 | # of the License, or (at your option) any later version. |
|
10 | 10 | # |
|
11 | 11 | # This program is distributed in the hope that it will be useful, |
|
12 | 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
13 | 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
14 | 14 | # GNU General Public License for more details. |
|
15 | 15 | # |
|
16 | 16 | # You should have received a copy of the GNU General Public License |
|
17 | 17 | # along with this program; if not, write to the Free Software |
|
18 | 18 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
19 | 19 | |
|
20 | 20 | module MembersHelper |
|
21 | def render_principals_for_new_members(project) | |
|
22 | scope = Principal.active.not_member_of(project).like(params[:q]).order('type, login, lastname ASC') | |
|
23 | principal_count = scope.count | |
|
24 | principal_pages = Redmine::Pagination::Paginator.new principal_count, 100, params['page'] | |
|
25 | principals = scope.offset(principal_pages.offset).limit(principal_pages.per_page).all | |
|
26 | ||
|
27 | s = content_tag('div', principals_check_box_tags('membership[user_ids][]', principals), :id => 'principals') | |
|
28 | ||
|
29 | links = pagination_links_full(principal_pages, principal_count, :per_page_links => false) {|text, parameters, options| | |
|
30 | link_to text, autocomplete_project_memberships_path(project, parameters.merge(:q => params[:q], :format => 'js')), :remote => true | |
|
31 | } | |
|
32 | ||
|
33 | s + content_tag('p', links, :class => 'pagination') | |
|
34 | end | |
|
21 | 35 | end |
@@ -1,43 +1,39 | |||
|
1 | 1 | <div class="splitcontentleft"> |
|
2 | 2 | <% if @group.users.any? %> |
|
3 | 3 | <table class="list users"> |
|
4 | 4 | <thead><tr> |
|
5 | 5 | <th><%= l(:label_user) %></th> |
|
6 | 6 | <th style="width:15%"></th> |
|
7 | 7 | </tr></thead> |
|
8 | 8 | <tbody> |
|
9 | 9 | <% @group.users.sort.each do |user| %> |
|
10 | 10 | <tr id="user-<%= user.id %>" class="<%= cycle 'odd', 'even' %>"> |
|
11 | 11 | <td class="user"><%= link_to_user user %></td> |
|
12 | 12 | <td class="buttons"> |
|
13 | 13 | <%= delete_link group_user_path(@group, :user_id => user), :remote => true %> |
|
14 | 14 | </td> |
|
15 | 15 | </tr> |
|
16 | 16 | <% end %> |
|
17 | 17 | </tbody> |
|
18 | 18 | </table> |
|
19 | 19 | <% else %> |
|
20 | 20 | <p class="nodata"><%= l(:label_no_data) %></p> |
|
21 | 21 | <% end %> |
|
22 | 22 | </div> |
|
23 | 23 | |
|
24 | 24 | <div class="splitcontentright"> |
|
25 | <% users = User.active.not_in_group(@group).all(:limit => 100) %> | |
|
26 | <% if users.any? %> | |
|
27 | 25 | <%= form_for(@group, :remote => true, :url => group_users_path(@group), |
|
28 | 26 | :html => {:method => :post}) do |f| %> |
|
29 | 27 | <fieldset><legend><%=l(:label_user_new)%></legend> |
|
30 | 28 | |
|
31 | 29 | <p><%= label_tag "user_search", l(:label_user_search) %><%= text_field_tag 'user_search', nil %></p> |
|
32 |
<%= javascript_tag "observeSearchfield('user_search', |
|
|
30 | <%= javascript_tag "observeSearchfield('user_search', null, '#{ escape_javascript autocomplete_for_user_group_path(@group) }')" %> | |
|
33 | 31 | |
|
34 | 32 | <div id="users"> |
|
35 | <%= principals_check_box_tags 'user_ids[]', users %> | |
|
33 | <%= render_principals_for_new_group_users(@group) %> | |
|
36 | 34 | </div> |
|
37 | 35 | |
|
38 | 36 | <p><%= submit_tag l(:button_add) %></p> |
|
39 | 37 | </fieldset> |
|
40 | 38 | <% end %> |
|
41 | <% end %> | |
|
42 | ||
|
43 | 39 | </div> |
@@ -1,77 +1,75 | |||
|
1 | 1 | <%= error_messages_for 'member' %> |
|
2 | 2 | <% roles = Role.find_all_givable |
|
3 | 3 | members = @project.member_principals.includes(:roles, :principal).all.sort %> |
|
4 | 4 | |
|
5 | 5 | <div class="splitcontentleft"> |
|
6 | 6 | <% if members.any? %> |
|
7 | 7 | <table class="list members"> |
|
8 | 8 | <thead><tr> |
|
9 | 9 | <th><%= l(:label_user) %> / <%= l(:label_group) %></th> |
|
10 | 10 | <th><%= l(:label_role_plural) %></th> |
|
11 | 11 | <th style="width:15%"></th> |
|
12 | 12 | <%= call_hook(:view_projects_settings_members_table_header, :project => @project) %> |
|
13 | 13 | </tr></thead> |
|
14 | 14 | <tbody> |
|
15 | 15 | <% members.each do |member| %> |
|
16 | 16 | <% next if member.new_record? %> |
|
17 | 17 | <tr id="member-<%= member.id %>" class="<%= cycle 'odd', 'even' %> member"> |
|
18 | 18 | <td class="<%= member.principal.class.name.downcase %>"><%= link_to_user member.principal %></td> |
|
19 | 19 | <td class="roles"> |
|
20 | 20 | <span id="member-<%= member.id %>-roles"><%=h member.roles.sort.collect(&:to_s).join(', ') %></span> |
|
21 | 21 | <%= form_for(member, {:as => :membership, :remote => true, :url => membership_path(member), |
|
22 | 22 | :method => :put, |
|
23 | 23 | :html => { :id => "member-#{member.id}-roles-form", :class => 'hol' }} |
|
24 | 24 | ) do |f| %> |
|
25 | 25 | <p><% roles.each do |role| %> |
|
26 | 26 | <label><%= check_box_tag 'membership[role_ids][]', role.id, member.roles.include?(role), |
|
27 | 27 | :disabled => member.member_roles.detect {|mr| mr.role_id == role.id && !mr.inherited_from.nil?} %> <%=h role %></label><br /> |
|
28 | 28 | <% end %></p> |
|
29 | 29 | <%= hidden_field_tag 'membership[role_ids][]', '' %> |
|
30 | 30 | <p><%= submit_tag l(:button_change), :class => "small" %> |
|
31 | 31 | <%= link_to_function l(:button_cancel), |
|
32 | 32 | "$('#member-#{member.id}-roles').show(); $('#member-#{member.id}-roles-form').hide(); return false;" |
|
33 | 33 | %></p> |
|
34 | 34 | <% end %> |
|
35 | 35 | </td> |
|
36 | 36 | <td class="buttons"> |
|
37 | 37 | <%= link_to_function l(:button_edit), |
|
38 | 38 | "$('#member-#{member.id}-roles').hide(); $('#member-#{member.id}-roles-form').show(); return false;", |
|
39 | 39 | :class => 'icon icon-edit' %> |
|
40 | 40 | <%= delete_link membership_path(member), |
|
41 | 41 | :remote => true, |
|
42 | 42 | :data => (!User.current.admin? && member.include?(User.current) ? {:confirm => l(:text_own_membership_delete_confirmation)} : {}) if member.deletable? %> |
|
43 | 43 | </td> |
|
44 | 44 | <%= call_hook(:view_projects_settings_members_table_row, { :project => @project, :member => member}) %> |
|
45 | 45 | </tr> |
|
46 | 46 | <% end; reset_cycle %> |
|
47 | 47 | </tbody> |
|
48 | 48 | </table> |
|
49 | 49 | <% else %> |
|
50 | 50 | <p class="nodata"><%= l(:label_no_data) %></p> |
|
51 | 51 | <% end %> |
|
52 | 52 | </div> |
|
53 | 53 | |
|
54 | <% principals = Principal.active.not_member_of(@project).all(:limit => 100, :order => 'type, login, lastname ASC') %> | |
|
55 | ||
|
56 | 54 | <div class="splitcontentright"> |
|
57 |
<% if roles.any? |
|
|
55 | <% if roles.any? %> | |
|
58 | 56 | <%= form_for(@member, {:as => :membership, :url => project_memberships_path(@project), :remote => true, :method => :post}) do |f| %> |
|
59 | 57 | <fieldset><legend><%=l(:label_member_new)%></legend> |
|
60 | 58 | |
|
61 | 59 | <p><%= label_tag "principal_search", l(:label_principal_search) %><%= text_field_tag 'principal_search', nil %></p> |
|
62 |
<%= javascript_tag "observeSearchfield('principal_search', |
|
|
60 | <%= javascript_tag "observeSearchfield('principal_search', null, '#{ escape_javascript autocomplete_project_memberships_path(@project, :format => 'js') }')" %> | |
|
63 | 61 | |
|
64 | <div id="principals"> | |
|
65 | <%= principals_check_box_tags 'membership[user_ids][]', principals %> | |
|
62 | <div id="principals_for_new_member"> | |
|
63 | <%= render_principals_for_new_members(@project) %> | |
|
66 | 64 | </div> |
|
67 | 65 | |
|
68 | 66 | <p><%= l(:label_role_plural) %>: |
|
69 | 67 | <% roles.each do |role| %> |
|
70 | 68 | <label><%= check_box_tag 'membership[role_ids][]', role.id %> <%=h role %></label> |
|
71 | 69 | <% end %></p> |
|
72 | 70 | |
|
73 | 71 | <p><%= submit_tag l(:button_add), :id => 'member-add-submit' %></p> |
|
74 | 72 | </fieldset> |
|
75 | 73 | <% end %> |
|
76 | 74 | <% end %> |
|
77 | 75 | </div> |
@@ -1,590 +1,590 | |||
|
1 | 1 | /* Redmine - project management software |
|
2 | 2 | Copyright (C) 2006-2013 Jean-Philippe Lang */ |
|
3 | 3 | |
|
4 | 4 | function checkAll(id, checked) { |
|
5 | 5 | if (checked) { |
|
6 | 6 | $('#'+id).find('input[type=checkbox]').attr('checked', true); |
|
7 | 7 | } else { |
|
8 | 8 | $('#'+id).find('input[type=checkbox]').removeAttr('checked'); |
|
9 | 9 | } |
|
10 | 10 | } |
|
11 | 11 | |
|
12 | 12 | function toggleCheckboxesBySelector(selector) { |
|
13 | 13 | var all_checked = true; |
|
14 | 14 | $(selector).each(function(index) { |
|
15 | 15 | if (!$(this).is(':checked')) { all_checked = false; } |
|
16 | 16 | }); |
|
17 | 17 | $(selector).attr('checked', !all_checked) |
|
18 | 18 | } |
|
19 | 19 | |
|
20 | 20 | function showAndScrollTo(id, focus) { |
|
21 | 21 | $('#'+id).show(); |
|
22 | 22 | if (focus!=null) { |
|
23 | 23 | $('#'+focus).focus(); |
|
24 | 24 | } |
|
25 | 25 | $('html, body').animate({scrollTop: $('#'+id).offset().top}, 100); |
|
26 | 26 | } |
|
27 | 27 | |
|
28 | 28 | function toggleRowGroup(el) { |
|
29 | 29 | var tr = $(el).parents('tr').first(); |
|
30 | 30 | var n = tr.next(); |
|
31 | 31 | tr.toggleClass('open'); |
|
32 | 32 | while (n.length && !n.hasClass('group')) { |
|
33 | 33 | n.toggle(); |
|
34 | 34 | n = n.next('tr'); |
|
35 | 35 | } |
|
36 | 36 | } |
|
37 | 37 | |
|
38 | 38 | function collapseAllRowGroups(el) { |
|
39 | 39 | var tbody = $(el).parents('tbody').first(); |
|
40 | 40 | tbody.children('tr').each(function(index) { |
|
41 | 41 | if ($(this).hasClass('group')) { |
|
42 | 42 | $(this).removeClass('open'); |
|
43 | 43 | } else { |
|
44 | 44 | $(this).hide(); |
|
45 | 45 | } |
|
46 | 46 | }); |
|
47 | 47 | } |
|
48 | 48 | |
|
49 | 49 | function expandAllRowGroups(el) { |
|
50 | 50 | var tbody = $(el).parents('tbody').first(); |
|
51 | 51 | tbody.children('tr').each(function(index) { |
|
52 | 52 | if ($(this).hasClass('group')) { |
|
53 | 53 | $(this).addClass('open'); |
|
54 | 54 | } else { |
|
55 | 55 | $(this).show(); |
|
56 | 56 | } |
|
57 | 57 | }); |
|
58 | 58 | } |
|
59 | 59 | |
|
60 | 60 | function toggleAllRowGroups(el) { |
|
61 | 61 | var tr = $(el).parents('tr').first(); |
|
62 | 62 | if (tr.hasClass('open')) { |
|
63 | 63 | collapseAllRowGroups(el); |
|
64 | 64 | } else { |
|
65 | 65 | expandAllRowGroups(el); |
|
66 | 66 | } |
|
67 | 67 | } |
|
68 | 68 | |
|
69 | 69 | function toggleFieldset(el) { |
|
70 | 70 | var fieldset = $(el).parents('fieldset').first(); |
|
71 | 71 | fieldset.toggleClass('collapsed'); |
|
72 | 72 | fieldset.children('div').toggle(); |
|
73 | 73 | } |
|
74 | 74 | |
|
75 | 75 | function hideFieldset(el) { |
|
76 | 76 | var fieldset = $(el).parents('fieldset').first(); |
|
77 | 77 | fieldset.toggleClass('collapsed'); |
|
78 | 78 | fieldset.children('div').hide(); |
|
79 | 79 | } |
|
80 | 80 | |
|
81 | 81 | function initFilters(){ |
|
82 | 82 | $('#add_filter_select').change(function(){ |
|
83 | 83 | addFilter($(this).val(), '', []); |
|
84 | 84 | }); |
|
85 | 85 | $('#filters-table td.field input[type=checkbox]').each(function(){ |
|
86 | 86 | toggleFilter($(this).val()); |
|
87 | 87 | }); |
|
88 | 88 | $('#filters-table td.field input[type=checkbox]').live('click',function(){ |
|
89 | 89 | toggleFilter($(this).val()); |
|
90 | 90 | }); |
|
91 | 91 | $('#filters-table .toggle-multiselect').live('click',function(){ |
|
92 | 92 | toggleMultiSelect($(this).siblings('select')); |
|
93 | 93 | }); |
|
94 | 94 | $('#filters-table input[type=text]').live('keypress', function(e){ |
|
95 | 95 | if (e.keyCode == 13) submit_query_form("query_form"); |
|
96 | 96 | }); |
|
97 | 97 | } |
|
98 | 98 | |
|
99 | 99 | function addFilter(field, operator, values) { |
|
100 | 100 | var fieldId = field.replace('.', '_'); |
|
101 | 101 | var tr = $('#tr_'+fieldId); |
|
102 | 102 | if (tr.length > 0) { |
|
103 | 103 | tr.show(); |
|
104 | 104 | } else { |
|
105 | 105 | buildFilterRow(field, operator, values); |
|
106 | 106 | } |
|
107 | 107 | $('#cb_'+fieldId).attr('checked', true); |
|
108 | 108 | toggleFilter(field); |
|
109 | 109 | $('#add_filter_select').val('').children('option').each(function(){ |
|
110 | 110 | if ($(this).attr('value') == field) { |
|
111 | 111 | $(this).attr('disabled', true); |
|
112 | 112 | } |
|
113 | 113 | }); |
|
114 | 114 | } |
|
115 | 115 | |
|
116 | 116 | function buildFilterRow(field, operator, values) { |
|
117 | 117 | var fieldId = field.replace('.', '_'); |
|
118 | 118 | var filterTable = $("#filters-table"); |
|
119 | 119 | var filterOptions = availableFilters[field]; |
|
120 | 120 | var operators = operatorByType[filterOptions['type']]; |
|
121 | 121 | var filterValues = filterOptions['values']; |
|
122 | 122 | var i, select; |
|
123 | 123 | |
|
124 | 124 | var tr = $('<tr class="filter">').attr('id', 'tr_'+fieldId).html( |
|
125 | 125 | '<td class="field"><input checked="checked" id="cb_'+fieldId+'" name="f[]" value="'+field+'" type="checkbox"><label for="cb_'+fieldId+'"> '+filterOptions['name']+'</label></td>' + |
|
126 | 126 | '<td class="operator"><select id="operators_'+fieldId+'" name="op['+field+']"></td>' + |
|
127 | 127 | '<td class="values"></td>' |
|
128 | 128 | ); |
|
129 | 129 | filterTable.append(tr); |
|
130 | 130 | |
|
131 | 131 | select = tr.find('td.operator select'); |
|
132 | 132 | for (i=0;i<operators.length;i++){ |
|
133 | 133 | var option = $('<option>').val(operators[i]).text(operatorLabels[operators[i]]); |
|
134 | 134 | if (operators[i] == operator) {option.attr('selected', true)}; |
|
135 | 135 | select.append(option); |
|
136 | 136 | } |
|
137 | 137 | select.change(function(){toggleOperator(field)}); |
|
138 | 138 | |
|
139 | 139 | switch (filterOptions['type']){ |
|
140 | 140 | case "list": |
|
141 | 141 | case "list_optional": |
|
142 | 142 | case "list_status": |
|
143 | 143 | case "list_subprojects": |
|
144 | 144 | tr.find('td.values').append( |
|
145 | 145 | '<span style="display:none;"><select class="value" id="values_'+fieldId+'_1" name="v['+field+'][]"></select>' + |
|
146 | 146 | ' <span class="toggle-multiselect"> </span></span>' |
|
147 | 147 | ); |
|
148 | 148 | select = tr.find('td.values select'); |
|
149 | 149 | if (values.length > 1) {select.attr('multiple', true)}; |
|
150 | 150 | for (i=0;i<filterValues.length;i++){ |
|
151 | 151 | var filterValue = filterValues[i]; |
|
152 | 152 | var option = $('<option>'); |
|
153 | 153 | if ($.isArray(filterValue)) { |
|
154 | 154 | option.val(filterValue[1]).text(filterValue[0]); |
|
155 | 155 | if ($.inArray(filterValue[1], values) > -1) {option.attr('selected', true);} |
|
156 | 156 | } else { |
|
157 | 157 | option.val(filterValue).text(filterValue); |
|
158 | 158 | if ($.inArray(filterValue, values) > -1) {option.attr('selected', true);} |
|
159 | 159 | } |
|
160 | 160 | select.append(option); |
|
161 | 161 | } |
|
162 | 162 | break; |
|
163 | 163 | case "date": |
|
164 | 164 | case "date_past": |
|
165 | 165 | tr.find('td.values').append( |
|
166 | 166 | '<span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'_1" size="10" class="value date_value" /></span>' + |
|
167 | 167 | ' <span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'_2" size="10" class="value date_value" /></span>' + |
|
168 | 168 | ' <span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'" size="3" class="value" /> '+labelDayPlural+'</span>' |
|
169 | 169 | ); |
|
170 | 170 | $('#values_'+fieldId+'_1').val(values[0]).datepicker(datepickerOptions); |
|
171 | 171 | $('#values_'+fieldId+'_2').val(values[1]).datepicker(datepickerOptions); |
|
172 | 172 | $('#values_'+fieldId).val(values[0]); |
|
173 | 173 | break; |
|
174 | 174 | case "string": |
|
175 | 175 | case "text": |
|
176 | 176 | tr.find('td.values').append( |
|
177 | 177 | '<span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'" size="30" class="value" /></span>' |
|
178 | 178 | ); |
|
179 | 179 | $('#values_'+fieldId).val(values[0]); |
|
180 | 180 | break; |
|
181 | 181 | case "relation": |
|
182 | 182 | tr.find('td.values').append( |
|
183 | 183 | '<span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'" size="6" class="value" /></span>' + |
|
184 | 184 | '<span style="display:none;"><select class="value" name="v['+field+'][]" id="values_'+fieldId+'_1"></select></span>' |
|
185 | 185 | ); |
|
186 | 186 | $('#values_'+fieldId).val(values[0]); |
|
187 | 187 | select = tr.find('td.values select'); |
|
188 | 188 | for (i=0;i<allProjects.length;i++){ |
|
189 | 189 | var filterValue = allProjects[i]; |
|
190 | 190 | var option = $('<option>'); |
|
191 | 191 | option.val(filterValue[1]).text(filterValue[0]); |
|
192 | 192 | if (values[0] == filterValue[1]) {option.attr('selected', true)}; |
|
193 | 193 | select.append(option); |
|
194 | 194 | } |
|
195 | 195 | case "integer": |
|
196 | 196 | case "float": |
|
197 | 197 | tr.find('td.values').append( |
|
198 | 198 | '<span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'_1" size="6" class="value" /></span>' + |
|
199 | 199 | ' <span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'_2" size="6" class="value" /></span>' |
|
200 | 200 | ); |
|
201 | 201 | $('#values_'+fieldId+'_1').val(values[0]); |
|
202 | 202 | $('#values_'+fieldId+'_2').val(values[1]); |
|
203 | 203 | break; |
|
204 | 204 | } |
|
205 | 205 | } |
|
206 | 206 | |
|
207 | 207 | function toggleFilter(field) { |
|
208 | 208 | var fieldId = field.replace('.', '_'); |
|
209 | 209 | if ($('#cb_' + fieldId).is(':checked')) { |
|
210 | 210 | $("#operators_" + fieldId).show().removeAttr('disabled'); |
|
211 | 211 | toggleOperator(field); |
|
212 | 212 | } else { |
|
213 | 213 | $("#operators_" + fieldId).hide().attr('disabled', true); |
|
214 | 214 | enableValues(field, []); |
|
215 | 215 | } |
|
216 | 216 | } |
|
217 | 217 | |
|
218 | 218 | function enableValues(field, indexes) { |
|
219 | 219 | var fieldId = field.replace('.', '_'); |
|
220 | 220 | $('#tr_'+fieldId+' td.values .value').each(function(index) { |
|
221 | 221 | if ($.inArray(index, indexes) >= 0) { |
|
222 | 222 | $(this).removeAttr('disabled'); |
|
223 | 223 | $(this).parents('span').first().show(); |
|
224 | 224 | } else { |
|
225 | 225 | $(this).val(''); |
|
226 | 226 | $(this).attr('disabled', true); |
|
227 | 227 | $(this).parents('span').first().hide(); |
|
228 | 228 | } |
|
229 | 229 | |
|
230 | 230 | if ($(this).hasClass('group')) { |
|
231 | 231 | $(this).addClass('open'); |
|
232 | 232 | } else { |
|
233 | 233 | $(this).show(); |
|
234 | 234 | } |
|
235 | 235 | }); |
|
236 | 236 | } |
|
237 | 237 | |
|
238 | 238 | function toggleOperator(field) { |
|
239 | 239 | var fieldId = field.replace('.', '_'); |
|
240 | 240 | var operator = $("#operators_" + fieldId); |
|
241 | 241 | switch (operator.val()) { |
|
242 | 242 | case "!*": |
|
243 | 243 | case "*": |
|
244 | 244 | case "t": |
|
245 | 245 | case "ld": |
|
246 | 246 | case "w": |
|
247 | 247 | case "lw": |
|
248 | 248 | case "l2w": |
|
249 | 249 | case "m": |
|
250 | 250 | case "lm": |
|
251 | 251 | case "y": |
|
252 | 252 | case "o": |
|
253 | 253 | case "c": |
|
254 | 254 | enableValues(field, []); |
|
255 | 255 | break; |
|
256 | 256 | case "><": |
|
257 | 257 | enableValues(field, [0,1]); |
|
258 | 258 | break; |
|
259 | 259 | case "<t+": |
|
260 | 260 | case ">t+": |
|
261 | 261 | case "><t+": |
|
262 | 262 | case "t+": |
|
263 | 263 | case ">t-": |
|
264 | 264 | case "<t-": |
|
265 | 265 | case "><t-": |
|
266 | 266 | case "t-": |
|
267 | 267 | enableValues(field, [2]); |
|
268 | 268 | break; |
|
269 | 269 | case "=p": |
|
270 | 270 | case "=!p": |
|
271 | 271 | case "!p": |
|
272 | 272 | enableValues(field, [1]); |
|
273 | 273 | break; |
|
274 | 274 | default: |
|
275 | 275 | enableValues(field, [0]); |
|
276 | 276 | break; |
|
277 | 277 | } |
|
278 | 278 | } |
|
279 | 279 | |
|
280 | 280 | function toggleMultiSelect(el) { |
|
281 | 281 | if (el.attr('multiple')) { |
|
282 | 282 | el.removeAttr('multiple'); |
|
283 | 283 | } else { |
|
284 | 284 | el.attr('multiple', true); |
|
285 | 285 | } |
|
286 | 286 | } |
|
287 | 287 | |
|
288 | 288 | function submit_query_form(id) { |
|
289 | 289 | selectAllOptions("selected_columns"); |
|
290 | 290 | $('#'+id).submit(); |
|
291 | 291 | } |
|
292 | 292 | |
|
293 | 293 | function showTab(name) { |
|
294 | 294 | $('div#content .tab-content').hide(); |
|
295 | 295 | $('div.tabs a').removeClass('selected'); |
|
296 | 296 | $('#tab-content-' + name).show(); |
|
297 | 297 | $('#tab-' + name).addClass('selected'); |
|
298 | 298 | return false; |
|
299 | 299 | } |
|
300 | 300 | |
|
301 | 301 | function moveTabRight(el) { |
|
302 | 302 | var lis = $(el).parents('div.tabs').first().find('ul').children(); |
|
303 | 303 | var tabsWidth = 0; |
|
304 | 304 | var i = 0; |
|
305 | 305 | lis.each(function(){ |
|
306 | 306 | if ($(this).is(':visible')) { |
|
307 | 307 | tabsWidth += $(this).width() + 6; |
|
308 | 308 | } |
|
309 | 309 | }); |
|
310 | 310 | if (tabsWidth < $(el).parents('div.tabs').first().width() - 60) { return; } |
|
311 | 311 | while (i<lis.length && !lis.eq(i).is(':visible')) { i++; } |
|
312 | 312 | lis.eq(i).hide(); |
|
313 | 313 | } |
|
314 | 314 | |
|
315 | 315 | function moveTabLeft(el) { |
|
316 | 316 | var lis = $(el).parents('div.tabs').first().find('ul').children(); |
|
317 | 317 | var i = 0; |
|
318 | 318 | while (i<lis.length && !lis.eq(i).is(':visible')) { i++; } |
|
319 | 319 | if (i>0) { |
|
320 | 320 | lis.eq(i-1).show(); |
|
321 | 321 | } |
|
322 | 322 | } |
|
323 | 323 | |
|
324 | 324 | function displayTabsButtons() { |
|
325 | 325 | var lis; |
|
326 | 326 | var tabsWidth = 0; |
|
327 | 327 | var el; |
|
328 | 328 | $('div.tabs').each(function() { |
|
329 | 329 | el = $(this); |
|
330 | 330 | lis = el.find('ul').children(); |
|
331 | 331 | lis.each(function(){ |
|
332 | 332 | if ($(this).is(':visible')) { |
|
333 | 333 | tabsWidth += $(this).width() + 6; |
|
334 | 334 | } |
|
335 | 335 | }); |
|
336 | 336 | if ((tabsWidth < el.width() - 60) && (lis.first().is(':visible'))) { |
|
337 | 337 | el.find('div.tabs-buttons').hide(); |
|
338 | 338 | } else { |
|
339 | 339 | el.find('div.tabs-buttons').show(); |
|
340 | 340 | } |
|
341 | 341 | }); |
|
342 | 342 | } |
|
343 | 343 | |
|
344 | 344 | function setPredecessorFieldsVisibility() { |
|
345 | 345 | var relationType = $('#relation_relation_type'); |
|
346 | 346 | if (relationType.val() == "precedes" || relationType.val() == "follows") { |
|
347 | 347 | $('#predecessor_fields').show(); |
|
348 | 348 | } else { |
|
349 | 349 | $('#predecessor_fields').hide(); |
|
350 | 350 | } |
|
351 | 351 | } |
|
352 | 352 | |
|
353 | 353 | function showModal(id, width) { |
|
354 | 354 | var el = $('#'+id).first(); |
|
355 | 355 | if (el.length == 0 || el.is(':visible')) {return;} |
|
356 | 356 | var title = el.find('h3.title').text(); |
|
357 | 357 | el.dialog({ |
|
358 | 358 | width: width, |
|
359 | 359 | modal: true, |
|
360 | 360 | resizable: false, |
|
361 | 361 | dialogClass: 'modal', |
|
362 | 362 | title: title |
|
363 | 363 | }); |
|
364 | 364 | el.find("input[type=text], input[type=submit]").first().focus(); |
|
365 | 365 | } |
|
366 | 366 | |
|
367 | 367 | function hideModal(el) { |
|
368 | 368 | var modal; |
|
369 | 369 | if (el) { |
|
370 | 370 | modal = $(el).parents('.ui-dialog-content'); |
|
371 | 371 | } else { |
|
372 | 372 | modal = $('#ajax-modal'); |
|
373 | 373 | } |
|
374 | 374 | modal.dialog("close"); |
|
375 | 375 | } |
|
376 | 376 | |
|
377 | 377 | function submitPreview(url, form, target) { |
|
378 | 378 | $.ajax({ |
|
379 | 379 | url: url, |
|
380 | 380 | type: 'post', |
|
381 | 381 | data: $('#'+form).serialize(), |
|
382 | 382 | success: function(data){ |
|
383 | 383 | $('#'+target).html(data); |
|
384 | 384 | } |
|
385 | 385 | }); |
|
386 | 386 | } |
|
387 | 387 | |
|
388 | 388 | function collapseScmEntry(id) { |
|
389 | 389 | $('.'+id).each(function() { |
|
390 | 390 | if ($(this).hasClass('open')) { |
|
391 | 391 | collapseScmEntry($(this).attr('id')); |
|
392 | 392 | } |
|
393 | 393 | $(this).hide(); |
|
394 | 394 | }); |
|
395 | 395 | $('#'+id).removeClass('open'); |
|
396 | 396 | } |
|
397 | 397 | |
|
398 | 398 | function expandScmEntry(id) { |
|
399 | 399 | $('.'+id).each(function() { |
|
400 | 400 | $(this).show(); |
|
401 | 401 | if ($(this).hasClass('loaded') && !$(this).hasClass('collapsed')) { |
|
402 | 402 | expandScmEntry($(this).attr('id')); |
|
403 | 403 | } |
|
404 | 404 | }); |
|
405 | 405 | $('#'+id).addClass('open'); |
|
406 | 406 | } |
|
407 | 407 | |
|
408 | 408 | function scmEntryClick(id, url) { |
|
409 | 409 | el = $('#'+id); |
|
410 | 410 | if (el.hasClass('open')) { |
|
411 | 411 | collapseScmEntry(id); |
|
412 | 412 | el.addClass('collapsed'); |
|
413 | 413 | return false; |
|
414 | 414 | } else if (el.hasClass('loaded')) { |
|
415 | 415 | expandScmEntry(id); |
|
416 | 416 | el.removeClass('collapsed'); |
|
417 | 417 | return false; |
|
418 | 418 | } |
|
419 | 419 | if (el.hasClass('loading')) { |
|
420 | 420 | return false; |
|
421 | 421 | } |
|
422 | 422 | el.addClass('loading'); |
|
423 | 423 | $.ajax({ |
|
424 | 424 | url: url, |
|
425 | 425 | success: function(data){ |
|
426 | 426 | el.after(data); |
|
427 | 427 | el.addClass('open').addClass('loaded').removeClass('loading'); |
|
428 | 428 | } |
|
429 | 429 | }); |
|
430 | 430 | return true; |
|
431 | 431 | } |
|
432 | 432 | |
|
433 | 433 | function randomKey(size) { |
|
434 | 434 | var chars = new Array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'); |
|
435 | 435 | var key = ''; |
|
436 | 436 | for (i = 0; i < size; i++) { |
|
437 | 437 | key += chars[Math.floor(Math.random() * chars.length)]; |
|
438 | 438 | } |
|
439 | 439 | return key; |
|
440 | 440 | } |
|
441 | 441 | |
|
442 | 442 | // Can't use Rails' remote select because we need the form data |
|
443 | 443 | function updateIssueFrom(url) { |
|
444 | 444 | $.ajax({ |
|
445 | 445 | url: url, |
|
446 | 446 | type: 'post', |
|
447 | 447 | data: $('#issue-form').serialize() |
|
448 | 448 | }); |
|
449 | 449 | } |
|
450 | 450 | |
|
451 | 451 | function updateBulkEditFrom(url) { |
|
452 | 452 | $.ajax({ |
|
453 | 453 | url: url, |
|
454 | 454 | type: 'post', |
|
455 | 455 | data: $('#bulk_edit_form').serialize() |
|
456 | 456 | }); |
|
457 | 457 | } |
|
458 | 458 | |
|
459 | 459 | function observeAutocompleteField(fieldId, url, options) { |
|
460 | 460 | $(document).ready(function() { |
|
461 | 461 | $('#'+fieldId).autocomplete($.extend({ |
|
462 | 462 | source: url, |
|
463 | 463 | minLength: 2, |
|
464 | 464 | search: function(){$('#'+fieldId).addClass('ajax-loading');}, |
|
465 | 465 | response: function(){$('#'+fieldId).removeClass('ajax-loading');}, |
|
466 | 466 | }, options)); |
|
467 | 467 | $('#'+fieldId).addClass('autocomplete'); |
|
468 | 468 | }); |
|
469 | 469 | } |
|
470 | 470 | |
|
471 | 471 | function observeSearchfield(fieldId, targetId, url) { |
|
472 | 472 | $('#'+fieldId).each(function() { |
|
473 | 473 | var $this = $(this); |
|
474 | 474 | $this.addClass('autocomplete'); |
|
475 | 475 | $this.attr('data-value-was', $this.val()); |
|
476 | 476 | var check = function() { |
|
477 | 477 | var val = $this.val(); |
|
478 | 478 | if ($this.attr('data-value-was') != val){ |
|
479 | 479 | $this.attr('data-value-was', val); |
|
480 | 480 | $.ajax({ |
|
481 | 481 | url: url, |
|
482 | 482 | type: 'get', |
|
483 | 483 | data: {q: $this.val()}, |
|
484 | success: function(data){ $('#'+targetId).html(data); }, | |
|
484 | success: function(data){ if(targetId) $('#'+targetId).html(data); }, | |
|
485 | 485 | beforeSend: function(){ $this.addClass('ajax-loading'); }, |
|
486 | 486 | complete: function(){ $this.removeClass('ajax-loading'); } |
|
487 | 487 | }); |
|
488 | 488 | } |
|
489 | 489 | }; |
|
490 | 490 | var reset = function() { |
|
491 | 491 | if (timer) { |
|
492 | 492 | clearInterval(timer); |
|
493 | 493 | timer = setInterval(check, 300); |
|
494 | 494 | } |
|
495 | 495 | }; |
|
496 | 496 | var timer = setInterval(check, 300); |
|
497 | 497 | $this.bind('keyup click mousemove', reset); |
|
498 | 498 | }); |
|
499 | 499 | } |
|
500 | 500 | |
|
501 | 501 | function observeProjectModules() { |
|
502 | 502 | var f = function() { |
|
503 | 503 | /* Hides trackers and issues custom fields on the new project form when issue_tracking module is disabled */ |
|
504 | 504 | if ($('#project_enabled_module_names_issue_tracking').attr('checked')) { |
|
505 | 505 | $('#project_trackers').show(); |
|
506 | 506 | }else{ |
|
507 | 507 | $('#project_trackers').hide(); |
|
508 | 508 | } |
|
509 | 509 | }; |
|
510 | 510 | |
|
511 | 511 | $(window).load(f); |
|
512 | 512 | $('#project_enabled_module_names_issue_tracking').change(f); |
|
513 | 513 | } |
|
514 | 514 | |
|
515 | 515 | function initMyPageSortable(list, url) { |
|
516 | 516 | $('#list-'+list).sortable({ |
|
517 | 517 | connectWith: '.block-receiver', |
|
518 | 518 | tolerance: 'pointer', |
|
519 | 519 | update: function(){ |
|
520 | 520 | $.ajax({ |
|
521 | 521 | url: url, |
|
522 | 522 | type: 'post', |
|
523 | 523 | data: {'blocks': $.map($('#list-'+list).children(), function(el){return $(el).attr('id');})} |
|
524 | 524 | }); |
|
525 | 525 | } |
|
526 | 526 | }); |
|
527 | 527 | $("#list-top, #list-left, #list-right").disableSelection(); |
|
528 | 528 | } |
|
529 | 529 | |
|
530 | 530 | var warnLeavingUnsavedMessage; |
|
531 | 531 | function warnLeavingUnsaved(message) { |
|
532 | 532 | warnLeavingUnsavedMessage = message; |
|
533 | 533 | |
|
534 | 534 | $('form').submit(function(){ |
|
535 | 535 | $('textarea').removeData('changed'); |
|
536 | 536 | }); |
|
537 | 537 | $('textarea').change(function(){ |
|
538 | 538 | $(this).data('changed', 'changed'); |
|
539 | 539 | }); |
|
540 | 540 | window.onbeforeunload = function(){ |
|
541 | 541 | var warn = false; |
|
542 | 542 | $('textarea').blur().each(function(){ |
|
543 | 543 | if ($(this).data('changed')) { |
|
544 | 544 | warn = true; |
|
545 | 545 | } |
|
546 | 546 | }); |
|
547 | 547 | if (warn) {return warnLeavingUnsavedMessage;} |
|
548 | 548 | }; |
|
549 | 549 | }; |
|
550 | 550 | |
|
551 | 551 | function setupAjaxIndicator() { |
|
552 | 552 | |
|
553 | 553 | $('#ajax-indicator').bind('ajaxSend', function(event, xhr, settings) { |
|
554 | 554 | |
|
555 | 555 | if ($('.ajax-loading').length == 0 && settings.contentType != 'application/octet-stream') { |
|
556 | 556 | $('#ajax-indicator').show(); |
|
557 | 557 | } |
|
558 | 558 | }); |
|
559 | 559 | |
|
560 | 560 | $('#ajax-indicator').bind('ajaxStop', function() { |
|
561 | 561 | $('#ajax-indicator').hide(); |
|
562 | 562 | }); |
|
563 | 563 | } |
|
564 | 564 | |
|
565 | 565 | function hideOnLoad() { |
|
566 | 566 | $('.hol').hide(); |
|
567 | 567 | } |
|
568 | 568 | |
|
569 | 569 | function addFormObserversForDoubleSubmit() { |
|
570 | 570 | $('form[method=post]').each(function() { |
|
571 | 571 | if (!$(this).hasClass('multiple-submit')) { |
|
572 | 572 | $(this).submit(function(form_submission) { |
|
573 | 573 | if ($(form_submission.target).attr('data-submitted')) { |
|
574 | 574 | form_submission.preventDefault(); |
|
575 | 575 | } else { |
|
576 | 576 | $(form_submission.target).attr('data-submitted', true); |
|
577 | 577 | } |
|
578 | 578 | }); |
|
579 | 579 | } |
|
580 | 580 | }); |
|
581 | 581 | } |
|
582 | 582 | |
|
583 | 583 | function blockEventPropagation(event) { |
|
584 | 584 | event.stopPropagation(); |
|
585 | 585 | event.preventDefault(); |
|
586 | 586 | } |
|
587 | 587 | |
|
588 | 588 | $(document).ready(setupAjaxIndicator); |
|
589 | 589 | $(document).ready(hideOnLoad); |
|
590 | 590 | $(document).ready(addFormObserversForDoubleSubmit); |
@@ -1,1147 +1,1147 | |||
|
1 | 1 | html {overflow-y:scroll;} |
|
2 | 2 | body { font-family: Verdana, sans-serif; font-size: 12px; color:#484848; margin: 0; padding: 0; min-width: 900px; } |
|
3 | 3 | |
|
4 | 4 | h1, h2, h3, h4 {font-family: "Trebuchet MS", Verdana, sans-serif;padding: 2px 10px 1px 0px;margin: 0 0 10px 0;} |
|
5 | 5 | #content h1, h2, h3, h4 {color: #555;} |
|
6 | 6 | h2, .wiki h1 {font-size: 20px;} |
|
7 | 7 | h3, .wiki h2 {font-size: 16px;} |
|
8 | 8 | h4, .wiki h3 {font-size: 13px;} |
|
9 | 9 | h4 {border-bottom: 1px dotted #bbb;} |
|
10 | 10 | |
|
11 | 11 | /***** Layout *****/ |
|
12 | 12 | #wrapper {background: white;} |
|
13 | 13 | |
|
14 | 14 | #top-menu {background: #3E5B76; color: #fff; height:1.8em; font-size: 0.8em; padding: 2px 2px 0px 6px;} |
|
15 | 15 | #top-menu ul {margin: 0; padding: 0;} |
|
16 | 16 | #top-menu li { |
|
17 | 17 | float:left; |
|
18 | 18 | list-style-type:none; |
|
19 | 19 | margin: 0px 0px 0px 0px; |
|
20 | 20 | padding: 0px 0px 0px 0px; |
|
21 | 21 | white-space:nowrap; |
|
22 | 22 | } |
|
23 | 23 | #top-menu a {color: #fff; margin-right: 8px; font-weight: bold;} |
|
24 | 24 | #top-menu #loggedas { float: right; margin-right: 0.5em; color: #fff; } |
|
25 | 25 | |
|
26 | 26 | #account {float:right;} |
|
27 | 27 | |
|
28 | 28 | #header {height:5.3em;margin:0;background-color:#628DB6;color:#f8f8f8; padding: 4px 8px 0px 6px; position:relative;} |
|
29 | 29 | #header a {color:#f8f8f8;} |
|
30 | 30 | #header h1 a.ancestor { font-size: 80%; } |
|
31 | 31 | #quick-search {float:right;} |
|
32 | 32 | |
|
33 | 33 | #main-menu {position: absolute; bottom: 0px; left:6px; margin-right: -500px;} |
|
34 | 34 | #main-menu ul {margin: 0; padding: 0;} |
|
35 | 35 | #main-menu li { |
|
36 | 36 | float:left; |
|
37 | 37 | list-style-type:none; |
|
38 | 38 | margin: 0px 2px 0px 0px; |
|
39 | 39 | padding: 0px 0px 0px 0px; |
|
40 | 40 | white-space:nowrap; |
|
41 | 41 | } |
|
42 | 42 | #main-menu li a { |
|
43 | 43 | display: block; |
|
44 | 44 | color: #fff; |
|
45 | 45 | text-decoration: none; |
|
46 | 46 | font-weight: bold; |
|
47 | 47 | margin: 0; |
|
48 | 48 | padding: 4px 10px 4px 10px; |
|
49 | 49 | } |
|
50 | 50 | #main-menu li a:hover {background:#759FCF; color:#fff;} |
|
51 | 51 | #main-menu li a.selected, #main-menu li a.selected:hover {background:#fff; color:#555;} |
|
52 | 52 | |
|
53 | 53 | #admin-menu ul {margin: 0; padding: 0;} |
|
54 | 54 | #admin-menu li {margin: 0; padding: 0 0 6px 0; list-style-type:none;} |
|
55 | 55 | |
|
56 | 56 | #admin-menu a { background-position: 0% 40%; background-repeat: no-repeat; padding-left: 20px; padding-top: 2px; padding-bottom: 3px;} |
|
57 | 57 | #admin-menu a.projects { background-image: url(../images/projects.png); } |
|
58 | 58 | #admin-menu a.users { background-image: url(../images/user.png); } |
|
59 | 59 | #admin-menu a.groups { background-image: url(../images/group.png); } |
|
60 | 60 | #admin-menu a.roles { background-image: url(../images/database_key.png); } |
|
61 | 61 | #admin-menu a.trackers { background-image: url(../images/ticket.png); } |
|
62 | 62 | #admin-menu a.issue_statuses { background-image: url(../images/ticket_edit.png); } |
|
63 | 63 | #admin-menu a.workflows { background-image: url(../images/ticket_go.png); } |
|
64 | 64 | #admin-menu a.custom_fields { background-image: url(../images/textfield.png); } |
|
65 | 65 | #admin-menu a.enumerations { background-image: url(../images/text_list_bullets.png); } |
|
66 | 66 | #admin-menu a.settings { background-image: url(../images/changeset.png); } |
|
67 | 67 | #admin-menu a.plugins { background-image: url(../images/plugin.png); } |
|
68 | 68 | #admin-menu a.info { background-image: url(../images/help.png); } |
|
69 | 69 | #admin-menu a.server_authentication { background-image: url(../images/server_key.png); } |
|
70 | 70 | |
|
71 | 71 | #main {background-color:#EEEEEE;} |
|
72 | 72 | |
|
73 | 73 | #sidebar{ float: right; width: 22%; position: relative; z-index: 9; padding: 0; margin: 0;} |
|
74 | 74 | * html #sidebar{ width: 22%; } |
|
75 | 75 | #sidebar h3{ font-size: 14px; margin-top:14px; color: #666; } |
|
76 | 76 | #sidebar hr{ width: 100%; margin: 0 auto; height: 1px; background: #ccc; border: 0; } |
|
77 | 77 | * html #sidebar hr{ width: 95%; position: relative; left: -6px; color: #ccc; } |
|
78 | 78 | #sidebar .contextual { margin-right: 1em; } |
|
79 | 79 | |
|
80 | 80 | #content { width: 75%; background-color: #fff; margin: 0px; border-right: 1px solid #ddd; padding: 6px 10px 10px 10px; z-index: 10; } |
|
81 | 81 | * html #content{ width: 75%; padding-left: 0; margin-top: 0px; padding: 6px 10px 10px 10px;} |
|
82 | 82 | html>body #content { min-height: 600px; } |
|
83 | 83 | * html body #content { height: 600px; } /* IE */ |
|
84 | 84 | |
|
85 | 85 | #main.nosidebar #sidebar{ display: none; } |
|
86 | 86 | #main.nosidebar #content{ width: auto; border-right: 0; } |
|
87 | 87 | |
|
88 | 88 | #footer {clear: both; border-top: 1px solid #bbb; font-size: 0.9em; color: #aaa; padding: 5px; text-align:center; background:#fff;} |
|
89 | 89 | |
|
90 | 90 | #login-form table {margin-top:5em; padding:1em; margin-left: auto; margin-right: auto; border: 2px solid #FDBF3B; background-color:#FFEBC1; } |
|
91 | 91 | #login-form table td {padding: 6px;} |
|
92 | 92 | #login-form label {font-weight: bold;} |
|
93 | 93 | #login-form input#username, #login-form input#password { width: 300px; } |
|
94 | 94 | |
|
95 | 95 | div.modal { border-radius:5px; background:#fff; z-index:50; padding:4px;} |
|
96 | 96 | div.modal h3.title {display:none;} |
|
97 | 97 | div.modal p.buttons {text-align:right; margin-bottom:0;} |
|
98 | 98 | |
|
99 | 99 | input#openid_url { background: url(../images/openid-bg.gif) no-repeat; background-color: #fff; background-position: 0 50%; padding-left: 18px; } |
|
100 | 100 | |
|
101 | 101 | .clear:after{ content: "."; display: block; height: 0; clear: both; visibility: hidden; } |
|
102 | 102 | |
|
103 | 103 | /***** Links *****/ |
|
104 | 104 | a, a:link, a:visited{ color: #169; text-decoration: none; } |
|
105 | 105 | a:hover, a:active{ color: #c61a1a; text-decoration: underline;} |
|
106 | 106 | a img{ border: 0; } |
|
107 | 107 | |
|
108 | 108 | a.issue.closed, a.issue.closed:link, a.issue.closed:visited { color: #999; text-decoration: line-through; } |
|
109 | 109 | a.project.closed, a.project.closed:link, a.project.closed:visited { color: #999; } |
|
110 | 110 | a.user.locked, a.user.locked:link, a.user.locked:visited {color: #999;} |
|
111 | 111 | |
|
112 | 112 | #sidebar a.selected {line-height:1.7em; padding:1px 3px 2px 2px; margin-left:-2px; background-color:#9DB9D5; color:#fff; border-radius:2px;} |
|
113 | 113 | #sidebar a.selected:hover {text-decoration:none;} |
|
114 | 114 | #admin-menu a {line-height:1.7em;} |
|
115 | 115 | #admin-menu a.selected {padding-left: 20px !important; background-position: 2px 40%;} |
|
116 | 116 | |
|
117 | 117 | a.collapsible {padding-left: 12px; background: url(../images/arrow_expanded.png) no-repeat -3px 40%;} |
|
118 | 118 | a.collapsible.collapsed {background: url(../images/arrow_collapsed.png) no-repeat -5px 40%;} |
|
119 | 119 | |
|
120 | 120 | a#toggle-completed-versions {color:#999;} |
|
121 | 121 | /***** Tables *****/ |
|
122 | 122 | table.list { border: 1px solid #e4e4e4; border-collapse: collapse; width: 100%; margin-bottom: 4px; } |
|
123 | 123 | table.list th { background-color:#EEEEEE; padding: 4px; white-space:nowrap; } |
|
124 | 124 | table.list td { vertical-align: top; padding-right:10px; } |
|
125 | 125 | table.list td.id { width: 2%; text-align: center;} |
|
126 | 126 | table.list td.checkbox { width: 15px; padding: 2px 0 0 0; } |
|
127 | 127 | table.list td.checkbox input {padding:0px;} |
|
128 | 128 | table.list td.buttons { width: 15%; white-space:nowrap; text-align: right; } |
|
129 | 129 | table.list td.buttons a { padding-right: 0.6em; } |
|
130 | 130 | table.list caption { text-align: left; padding: 0.5em 0.5em 0.5em 0; } |
|
131 | 131 | |
|
132 | 132 | tr.project td.name a { white-space:nowrap; } |
|
133 | 133 | tr.project.closed, tr.project.archived { color: #aaa; } |
|
134 | 134 | tr.project.closed a, tr.project.archived a { color: #aaa; } |
|
135 | 135 | |
|
136 | 136 | tr.project.idnt td.name span {background: url(../images/bullet_arrow_right.png) no-repeat 0 50%; padding-left: 16px;} |
|
137 | 137 | tr.project.idnt-1 td.name {padding-left: 0.5em;} |
|
138 | 138 | tr.project.idnt-2 td.name {padding-left: 2em;} |
|
139 | 139 | tr.project.idnt-3 td.name {padding-left: 3.5em;} |
|
140 | 140 | tr.project.idnt-4 td.name {padding-left: 5em;} |
|
141 | 141 | tr.project.idnt-5 td.name {padding-left: 6.5em;} |
|
142 | 142 | tr.project.idnt-6 td.name {padding-left: 8em;} |
|
143 | 143 | tr.project.idnt-7 td.name {padding-left: 9.5em;} |
|
144 | 144 | tr.project.idnt-8 td.name {padding-left: 11em;} |
|
145 | 145 | tr.project.idnt-9 td.name {padding-left: 12.5em;} |
|
146 | 146 | |
|
147 | 147 | tr.issue { text-align: center; white-space: nowrap; } |
|
148 | 148 | tr.issue td.subject, tr.issue td.category, td.assigned_to, tr.issue td.string, tr.issue td.text, tr.issue td.relations { white-space: normal; } |
|
149 | 149 | tr.issue td.subject, tr.issue td.relations { text-align: left; } |
|
150 | 150 | tr.issue td.done_ratio table.progress { margin-left:auto; margin-right: auto;} |
|
151 | 151 | tr.issue td.relations span {white-space: nowrap;} |
|
152 | 152 | table.issues td.description {color:#777; font-size:90%; padding:4px 4px 4px 24px; text-align:left; white-space:normal;} |
|
153 | 153 | table.issues td.description pre {white-space:normal;} |
|
154 | 154 | |
|
155 | 155 | tr.issue.idnt td.subject a {background: url(../images/bullet_arrow_right.png) no-repeat 0 50%; padding-left: 16px;} |
|
156 | 156 | tr.issue.idnt-1 td.subject {padding-left: 0.5em;} |
|
157 | 157 | tr.issue.idnt-2 td.subject {padding-left: 2em;} |
|
158 | 158 | tr.issue.idnt-3 td.subject {padding-left: 3.5em;} |
|
159 | 159 | tr.issue.idnt-4 td.subject {padding-left: 5em;} |
|
160 | 160 | tr.issue.idnt-5 td.subject {padding-left: 6.5em;} |
|
161 | 161 | tr.issue.idnt-6 td.subject {padding-left: 8em;} |
|
162 | 162 | tr.issue.idnt-7 td.subject {padding-left: 9.5em;} |
|
163 | 163 | tr.issue.idnt-8 td.subject {padding-left: 11em;} |
|
164 | 164 | tr.issue.idnt-9 td.subject {padding-left: 12.5em;} |
|
165 | 165 | |
|
166 | 166 | tr.entry { border: 1px solid #f8f8f8; } |
|
167 | 167 | tr.entry td { white-space: nowrap; } |
|
168 | 168 | tr.entry td.filename { width: 30%; } |
|
169 | 169 | tr.entry td.filename_no_report { width: 70%; } |
|
170 | 170 | tr.entry td.size { text-align: right; font-size: 90%; } |
|
171 | 171 | tr.entry td.revision, tr.entry td.author { text-align: center; } |
|
172 | 172 | tr.entry td.age { text-align: right; } |
|
173 | 173 | tr.entry.file td.filename a { margin-left: 16px; } |
|
174 | 174 | tr.entry.file td.filename_no_report a { margin-left: 16px; } |
|
175 | 175 | |
|
176 | 176 | tr span.expander {background-image: url(../images/bullet_toggle_plus.png); padding-left: 8px; margin-left: 0; cursor: pointer;} |
|
177 | 177 | tr.open span.expander {background-image: url(../images/bullet_toggle_minus.png);} |
|
178 | 178 | |
|
179 | 179 | tr.changeset { height: 20px } |
|
180 | 180 | tr.changeset ul, ol { margin-top: 0px; margin-bottom: 0px; } |
|
181 | 181 | tr.changeset td.revision_graph { width: 15%; background-color: #fffffb; } |
|
182 | 182 | tr.changeset td.author { text-align: center; width: 15%; white-space:nowrap;} |
|
183 | 183 | tr.changeset td.committed_on { text-align: center; width: 15%; white-space:nowrap;} |
|
184 | 184 | |
|
185 | 185 | table.files tr.file td { text-align: center; } |
|
186 | 186 | table.files tr.file td.filename { text-align: left; padding-left: 24px; } |
|
187 | 187 | table.files tr.file td.digest { font-size: 80%; } |
|
188 | 188 | |
|
189 | 189 | table.members td.roles, table.memberships td.roles { width: 45%; } |
|
190 | 190 | |
|
191 | 191 | tr.message { height: 2.6em; } |
|
192 | 192 | tr.message td.subject { padding-left: 20px; } |
|
193 | 193 | tr.message td.created_on { white-space: nowrap; } |
|
194 | 194 | tr.message td.last_message { font-size: 80%; white-space: nowrap; } |
|
195 | 195 | tr.message.locked td.subject { background: url(../images/locked.png) no-repeat 0 1px; } |
|
196 | 196 | tr.message.sticky td.subject { background: url(../images/bullet_go.png) no-repeat 0 1px; font-weight: bold; } |
|
197 | 197 | |
|
198 | 198 | tr.version.closed, tr.version.closed a { color: #999; } |
|
199 | 199 | tr.version td.name { padding-left: 20px; } |
|
200 | 200 | tr.version.shared td.name { background: url(../images/link.png) no-repeat 0% 70%; } |
|
201 | 201 | tr.version td.date, tr.version td.status, tr.version td.sharing { text-align: center; white-space:nowrap; } |
|
202 | 202 | |
|
203 | 203 | tr.user td { width:13%; } |
|
204 | 204 | tr.user td.email { width:18%; } |
|
205 | 205 | tr.user td { white-space: nowrap; } |
|
206 | 206 | tr.user.locked, tr.user.registered { color: #aaa; } |
|
207 | 207 | tr.user.locked a, tr.user.registered a { color: #aaa; } |
|
208 | 208 | |
|
209 | 209 | table.permissions td.role {color:#999;font-size:90%;font-weight:normal !important;text-align:center;vertical-align:bottom;} |
|
210 | 210 | |
|
211 | 211 | tr.wiki-page-version td.updated_on, tr.wiki-page-version td.author {text-align:center;} |
|
212 | 212 | |
|
213 | 213 | tr.time-entry { text-align: center; white-space: nowrap; } |
|
214 | 214 | tr.time-entry td.issue, tr.time-entry td.comments { text-align: left; white-space: normal; } |
|
215 | 215 | td.hours { text-align: right; font-weight: bold; padding-right: 0.5em; } |
|
216 | 216 | td.hours .hours-dec { font-size: 0.9em; } |
|
217 | 217 | |
|
218 | 218 | table.plugins td { vertical-align: middle; } |
|
219 | 219 | table.plugins td.configure { text-align: right; padding-right: 1em; } |
|
220 | 220 | table.plugins span.name { font-weight: bold; display: block; margin-bottom: 6px; } |
|
221 | 221 | table.plugins span.description { display: block; font-size: 0.9em; } |
|
222 | 222 | table.plugins span.url { display: block; font-size: 0.9em; } |
|
223 | 223 | |
|
224 | 224 | table.list tbody tr.group td { padding: 0.8em 0 0.5em 0.3em; font-weight: bold; border-bottom: 1px solid #ccc; } |
|
225 | 225 | table.list tbody tr.group span.count {position:relative; top:-1px; color:#fff; font-size:10px; background:#9DB9D5; padding:0px 6px 1px 6px; border-radius:3px; margin-left:4px;} |
|
226 | 226 | tr.group a.toggle-all { color: #aaa; font-size: 80%; font-weight: normal; display:none;} |
|
227 | 227 | tr.group:hover a.toggle-all { display:inline;} |
|
228 | 228 | a.toggle-all:hover {text-decoration:none;} |
|
229 | 229 | |
|
230 | 230 | table.list tbody tr:hover { background-color:#ffffdd; } |
|
231 | 231 | table.list tbody tr.group:hover { background-color:inherit; } |
|
232 | 232 | table td {padding:2px;} |
|
233 | 233 | table p {margin:0;} |
|
234 | 234 | .odd {background-color:#f6f7f8;} |
|
235 | 235 | .even {background-color: #fff;} |
|
236 | 236 | |
|
237 | 237 | a.sort { padding-right: 16px; background-position: 100% 50%; background-repeat: no-repeat; } |
|
238 | 238 | a.sort.asc { background-image: url(../images/sort_asc.png); } |
|
239 | 239 | a.sort.desc { background-image: url(../images/sort_desc.png); } |
|
240 | 240 | |
|
241 | 241 | table.attributes { width: 100% } |
|
242 | 242 | table.attributes th { vertical-align: top; text-align: left; } |
|
243 | 243 | table.attributes td { vertical-align: top; } |
|
244 | 244 | |
|
245 | 245 | table.boards a.board, h3.comments { background: url(../images/comment.png) no-repeat 0% 50%; padding-left: 20px; } |
|
246 | 246 | table.boards td.topic-count, table.boards td.message-count {text-align:center;} |
|
247 | 247 | table.boards td.last-message {font-size:80%;} |
|
248 | 248 | |
|
249 | 249 | table.messages td.author, table.messages td.created_on, table.messages td.reply-count {text-align:center;} |
|
250 | 250 | |
|
251 | 251 | table.query-columns { |
|
252 | 252 | border-collapse: collapse; |
|
253 | 253 | border: 0; |
|
254 | 254 | } |
|
255 | 255 | |
|
256 | 256 | table.query-columns td.buttons { |
|
257 | 257 | vertical-align: middle; |
|
258 | 258 | text-align: center; |
|
259 | 259 | } |
|
260 | 260 | |
|
261 | 261 | td.center {text-align:center;} |
|
262 | 262 | |
|
263 | 263 | h3.version { background: url(../images/package.png) no-repeat 0% 50%; padding-left: 20px; } |
|
264 | 264 | |
|
265 | 265 | div.issues h3 { background: url(../images/ticket.png) no-repeat 0% 50%; padding-left: 20px; } |
|
266 | 266 | div.members h3 { background: url(../images/group.png) no-repeat 0% 50%; padding-left: 20px; } |
|
267 | 267 | div.news h3 { background: url(../images/news.png) no-repeat 0% 50%; padding-left: 20px; } |
|
268 | 268 | div.projects h3 { background: url(../images/projects.png) no-repeat 0% 50%; padding-left: 20px; } |
|
269 | 269 | |
|
270 | 270 | #watchers ul {margin: 0; padding: 0;} |
|
271 | 271 | #watchers li {list-style-type:none;margin: 0px 2px 0px 0px; padding: 0px 0px 0px 0px;} |
|
272 | 272 | #watchers select {width: 95%; display: block;} |
|
273 | 273 | #watchers a.delete {opacity: 0.4;} |
|
274 | 274 | #watchers a.delete:hover {opacity: 1;} |
|
275 | 275 | #watchers img.gravatar {margin: 0 4px 2px 0;} |
|
276 | 276 | |
|
277 | 277 | span#watchers_inputs {overflow:auto; display:block;} |
|
278 | 278 | span.search_for_watchers {display:block;} |
|
279 | 279 | span.search_for_watchers, span.add_attachment {font-size:80%; line-height:2.5em;} |
|
280 | 280 | span.search_for_watchers a, span.add_attachment a {padding-left:16px; background: url(../images/bullet_add.png) no-repeat 0 50%; } |
|
281 | 281 | |
|
282 | 282 | |
|
283 | 283 | .highlight { background-color: #FCFD8D;} |
|
284 | 284 | .highlight.token-1 { background-color: #faa;} |
|
285 | 285 | .highlight.token-2 { background-color: #afa;} |
|
286 | 286 | .highlight.token-3 { background-color: #aaf;} |
|
287 | 287 | |
|
288 | 288 | .box{ |
|
289 | 289 | padding:6px; |
|
290 | 290 | margin-bottom: 10px; |
|
291 | 291 | background-color:#f6f6f6; |
|
292 | 292 | color:#505050; |
|
293 | 293 | line-height:1.5em; |
|
294 | 294 | border: 1px solid #e4e4e4; |
|
295 | 295 | } |
|
296 | 296 | |
|
297 | 297 | div.square { |
|
298 | 298 | border: 1px solid #999; |
|
299 | 299 | float: left; |
|
300 | 300 | margin: .3em .4em 0 .4em; |
|
301 | 301 | overflow: hidden; |
|
302 | 302 | width: .6em; height: .6em; |
|
303 | 303 | } |
|
304 | 304 | .contextual {float:right; white-space: nowrap; line-height:1.4em;margin-top:5px; padding-left: 10px; font-size:0.9em;} |
|
305 | 305 | .contextual input, .contextual select {font-size:0.9em;} |
|
306 | 306 | .message .contextual { margin-top: 0; } |
|
307 | 307 | |
|
308 | 308 | .splitcontent {overflow:auto;} |
|
309 | 309 | .splitcontentleft{float:left; width:49%;} |
|
310 | 310 | .splitcontentright{float:right; width:49%;} |
|
311 | 311 | form {display: inline;} |
|
312 | 312 | input, select {vertical-align: middle; margin-top: 1px; margin-bottom: 1px;} |
|
313 | 313 | fieldset {border: 1px solid #e4e4e4; margin:0;} |
|
314 | 314 | legend {color: #484848;} |
|
315 | 315 | hr { width: 100%; height: 1px; background: #ccc; border: 0;} |
|
316 | 316 | blockquote { font-style: italic; border-left: 3px solid #e0e0e0; padding-left: 0.6em; margin-left: 2.4em;} |
|
317 | 317 | blockquote blockquote { margin-left: 0;} |
|
318 | 318 | acronym { border-bottom: 1px dotted; cursor: help; } |
|
319 | 319 | textarea.wiki-edit {width:99%; resize:vertical;} |
|
320 | 320 | li p {margin-top: 0;} |
|
321 | 321 | div.issue {background:#ffffdd; padding:6px; margin-bottom:6px;border: 1px solid #d7d7d7;} |
|
322 | 322 | p.breadcrumb { font-size: 0.9em; margin: 4px 0 4px 0;} |
|
323 | 323 | p.subtitle { font-size: 0.9em; margin: -6px 0 12px 0; font-style: italic; } |
|
324 | 324 | p.footnote { font-size: 0.9em; margin-top: 0px; margin-bottom: 0px; } |
|
325 | 325 | |
|
326 | 326 | div.issue div.subject div div { padding-left: 16px; } |
|
327 | 327 | div.issue div.subject p {margin: 0; margin-bottom: 0.1em; font-size: 90%; color: #999;} |
|
328 | 328 | div.issue div.subject>div>p { margin-top: 0.5em; } |
|
329 | 329 | div.issue div.subject h3 {margin: 0; margin-bottom: 0.1em;} |
|
330 | 330 | div.issue span.private { position:relative; bottom: 2px; text-transform: uppercase; background: #d22; color: #fff; font-weight:bold; padding: 0px 2px 0px 2px; font-size: 60%; margin-right: 2px; border-radius: 2px;} |
|
331 | 331 | div.issue .next-prev-links {color:#999;} |
|
332 | 332 | div.issue table.attributes th {width:22%;} |
|
333 | 333 | div.issue table.attributes td {width:28%;} |
|
334 | 334 | |
|
335 | 335 | #issue_tree table.issues, #relations table.issues { border: 0; } |
|
336 | 336 | #issue_tree td.checkbox, #relations td.checkbox {display:none;} |
|
337 | 337 | #relations td.buttons {padding:0;} |
|
338 | 338 | |
|
339 | 339 | fieldset.collapsible { border-width: 1px 0 0 0; font-size: 0.9em; } |
|
340 | 340 | fieldset.collapsible legend { padding-left: 16px; background: url(../images/arrow_expanded.png) no-repeat 0% 40%; cursor:pointer; } |
|
341 | 341 | fieldset.collapsible.collapsed legend { background-image: url(../images/arrow_collapsed.png); } |
|
342 | 342 | |
|
343 | 343 | fieldset#date-range p { margin: 2px 0 2px 0; } |
|
344 | 344 | fieldset#filters table { border-collapse: collapse; } |
|
345 | 345 | fieldset#filters table td { padding: 0; vertical-align: middle; } |
|
346 | 346 | fieldset#filters tr.filter { height: 2.1em; } |
|
347 | 347 | fieldset#filters td.field { width:230px; } |
|
348 | 348 | fieldset#filters td.operator { width:180px; } |
|
349 | 349 | fieldset#filters td.operator select {max-width:170px;} |
|
350 | 350 | fieldset#filters td.values { white-space:nowrap; } |
|
351 | 351 | fieldset#filters td.values select {min-width:130px;} |
|
352 | 352 | fieldset#filters td.values input {height:1em;} |
|
353 | 353 | fieldset#filters td.add-filter { text-align: right; vertical-align: top; } |
|
354 | 354 | |
|
355 | 355 | .toggle-multiselect {background: url(../images/bullet_toggle_plus.png) no-repeat 0% 40%; padding-left:8px; margin-left:0; cursor:pointer;} |
|
356 | 356 | .buttons { font-size: 0.9em; margin-bottom: 1.4em; margin-top: 1em; } |
|
357 | 357 | |
|
358 | 358 | div#issue-changesets {float:right; width:45%; margin-left: 1em; margin-bottom: 1em; background: #fff; padding-left: 1em; font-size: 90%;} |
|
359 | 359 | div#issue-changesets div.changeset { padding: 4px;} |
|
360 | 360 | div#issue-changesets div.changeset { border-bottom: 1px solid #ddd; } |
|
361 | 361 | div#issue-changesets p { margin-top: 0; margin-bottom: 1em;} |
|
362 | 362 | |
|
363 | 363 | .journal ul.details img {margin:0 0 -3px 4px;} |
|
364 | 364 | div.journal {overflow:auto;} |
|
365 | 365 | div.journal.private-notes {border-left:2px solid #d22; padding-left:4px; margin-left:-6px;} |
|
366 | 366 | |
|
367 | 367 | div#activity dl, #search-results { margin-left: 2em; } |
|
368 | 368 | div#activity dd, #search-results dd { margin-bottom: 1em; padding-left: 18px; font-size: 0.9em; } |
|
369 | 369 | div#activity dt, #search-results dt { margin-bottom: 0px; padding-left: 20px; line-height: 18px; background-position: 0 50%; background-repeat: no-repeat; } |
|
370 | 370 | div#activity dt.me .time { border-bottom: 1px solid #999; } |
|
371 | 371 | div#activity dt .time { color: #777; font-size: 80%; } |
|
372 | 372 | div#activity dd .description, #search-results dd .description { font-style: italic; } |
|
373 | 373 | div#activity span.project:after, #search-results span.project:after { content: " -"; } |
|
374 | 374 | div#activity dd span.description, #search-results dd span.description { display:block; color: #808080; } |
|
375 | 375 | div#activity dt.grouped {margin-left:5em;} |
|
376 | 376 | div#activity dd.grouped {margin-left:9em;} |
|
377 | 377 | |
|
378 | 378 | #search-results dd { margin-bottom: 1em; padding-left: 20px; margin-left:0px; } |
|
379 | 379 | |
|
380 | 380 | div#search-results-counts {float:right;} |
|
381 | 381 | div#search-results-counts ul { margin-top: 0.5em; } |
|
382 | 382 | div#search-results-counts li { list-style-type:none; float: left; margin-left: 1em; } |
|
383 | 383 | |
|
384 | 384 | dt.issue { background-image: url(../images/ticket.png); } |
|
385 | 385 | dt.issue-edit { background-image: url(../images/ticket_edit.png); } |
|
386 | 386 | dt.issue-closed { background-image: url(../images/ticket_checked.png); } |
|
387 | 387 | dt.issue-note { background-image: url(../images/ticket_note.png); } |
|
388 | 388 | dt.changeset { background-image: url(../images/changeset.png); } |
|
389 | 389 | dt.news { background-image: url(../images/news.png); } |
|
390 | 390 | dt.message { background-image: url(../images/message.png); } |
|
391 | 391 | dt.reply { background-image: url(../images/comments.png); } |
|
392 | 392 | dt.wiki-page { background-image: url(../images/wiki_edit.png); } |
|
393 | 393 | dt.attachment { background-image: url(../images/attachment.png); } |
|
394 | 394 | dt.document { background-image: url(../images/document.png); } |
|
395 | 395 | dt.project { background-image: url(../images/projects.png); } |
|
396 | 396 | dt.time-entry { background-image: url(../images/time.png); } |
|
397 | 397 | |
|
398 | 398 | #search-results dt.issue.closed { background-image: url(../images/ticket_checked.png); } |
|
399 | 399 | |
|
400 | 400 | div#roadmap .related-issues { margin-bottom: 1em; } |
|
401 | 401 | div#roadmap .related-issues td.checkbox { display: none; } |
|
402 | 402 | div#roadmap .wiki h1:first-child { display: none; } |
|
403 | 403 | div#roadmap .wiki h1 { font-size: 120%; } |
|
404 | 404 | div#roadmap .wiki h2 { font-size: 110%; } |
|
405 | 405 | body.controller-versions.action-show div#roadmap .related-issues {width:70%;} |
|
406 | 406 | |
|
407 | 407 | div#version-summary { float:right; width:28%; margin-left: 16px; margin-bottom: 16px; background-color: #fff; } |
|
408 | 408 | div#version-summary fieldset { margin-bottom: 1em; } |
|
409 | 409 | div#version-summary fieldset.time-tracking table { width:100%; } |
|
410 | 410 | div#version-summary th, div#version-summary td.total-hours { text-align: right; } |
|
411 | 411 | |
|
412 | 412 | table#time-report td.hours, table#time-report th.period, table#time-report th.total { text-align: right; padding-right: 0.5em; } |
|
413 | 413 | table#time-report tbody tr.subtotal { font-style: italic; color:#777;} |
|
414 | 414 | table#time-report tbody tr.subtotal td.hours { color:#b0b0b0; } |
|
415 | 415 | table#time-report tbody tr.total { font-weight: bold; background-color:#EEEEEE; border-top:1px solid #e4e4e4;} |
|
416 | 416 | table#time-report .hours-dec { font-size: 0.9em; } |
|
417 | 417 | |
|
418 | 418 | div.wiki-page .contextual a {opacity: 0.4} |
|
419 | 419 | div.wiki-page .contextual a:hover {opacity: 1} |
|
420 | 420 | |
|
421 | 421 | form .attributes select { width: 60%; } |
|
422 | 422 | input#issue_subject { width: 99%; } |
|
423 | 423 | select#issue_done_ratio { width: 95px; } |
|
424 | 424 | |
|
425 | 425 | ul.projects {margin:0; padding-left:1em;} |
|
426 | 426 | ul.projects ul {padding-left:1.6em;} |
|
427 | 427 | ul.projects.root {margin:0; padding:0;} |
|
428 | 428 | ul.projects li {list-style-type:none;} |
|
429 | 429 | |
|
430 | 430 | #projects-index ul.projects ul.projects { border-left: 3px solid #e0e0e0; padding-left:1em;} |
|
431 | 431 | #projects-index ul.projects li.root {margin-bottom: 1em;} |
|
432 | 432 | #projects-index ul.projects li.child {margin-top: 1em;} |
|
433 | 433 | #projects-index ul.projects div.root a.project { font-family: "Trebuchet MS", Verdana, sans-serif; font-weight: bold; font-size: 16px; margin: 0 0 10px 0; } |
|
434 | 434 | .my-project { padding-left: 18px; background: url(../images/fav.png) no-repeat 0 50%; } |
|
435 | 435 | |
|
436 | 436 | #notified-projects ul, #tracker_project_ids ul {max-height:250px; overflow-y:auto;} |
|
437 | 437 | |
|
438 | 438 | #related-issues li img {vertical-align:middle;} |
|
439 | 439 | |
|
440 | 440 | ul.properties {padding:0; font-size: 0.9em; color: #777;} |
|
441 | 441 | ul.properties li {list-style-type:none;} |
|
442 | 442 | ul.properties li span {font-style:italic;} |
|
443 | 443 | |
|
444 | 444 | .total-hours { font-size: 110%; font-weight: bold; } |
|
445 | 445 | .total-hours span.hours-int { font-size: 120%; } |
|
446 | 446 | |
|
447 | 447 | .autoscroll {overflow-x: auto; padding:1px; margin-bottom: 1.2em;} |
|
448 | 448 | #user_login, #user_firstname, #user_lastname, #user_mail, #my_account_form select, #user_form select, #user_identity_url { width: 90%; } |
|
449 | 449 | |
|
450 | 450 | #workflow_copy_form select { width: 200px; } |
|
451 | 451 | table.transitions td.enabled {background: #bfb;} |
|
452 | 452 | table.fields_permissions select {font-size:90%} |
|
453 | 453 | table.fields_permissions td.readonly {background:#ddd;} |
|
454 | 454 | table.fields_permissions td.required {background:#d88;} |
|
455 | 455 | |
|
456 | 456 | textarea#custom_field_possible_values {width: 99%} |
|
457 | 457 | input#content_comments {width: 99%} |
|
458 | 458 | |
|
459 | 459 | p.pagination {margin-top:8px; font-size: 90%} |
|
460 | 460 | |
|
461 | 461 | /***** Tabular forms ******/ |
|
462 | 462 | .tabular p{ |
|
463 | 463 | margin: 0; |
|
464 | 464 | padding: 3px 0 3px 0; |
|
465 | 465 | padding-left: 180px; /* width of left column containing the label elements */ |
|
466 | 466 | min-height: 1.8em; |
|
467 | 467 | clear:left; |
|
468 | 468 | } |
|
469 | 469 | |
|
470 | 470 | html>body .tabular p {overflow:hidden;} |
|
471 | 471 | |
|
472 | 472 | .tabular label{ |
|
473 | 473 | font-weight: bold; |
|
474 | 474 | float: left; |
|
475 | 475 | text-align: right; |
|
476 | 476 | /* width of left column */ |
|
477 | 477 | margin-left: -180px; |
|
478 | 478 | /* width of labels. Should be smaller than left column to create some right margin */ |
|
479 | 479 | width: 175px; |
|
480 | 480 | } |
|
481 | 481 | |
|
482 | 482 | .tabular label.floating{ |
|
483 | 483 | font-weight: normal; |
|
484 | 484 | margin-left: 0px; |
|
485 | 485 | text-align: left; |
|
486 | 486 | width: 270px; |
|
487 | 487 | } |
|
488 | 488 | |
|
489 | 489 | .tabular label.block{ |
|
490 | 490 | font-weight: normal; |
|
491 | 491 | margin-left: 0px !important; |
|
492 | 492 | text-align: left; |
|
493 | 493 | float: none; |
|
494 | 494 | display: block; |
|
495 | 495 | width: auto; |
|
496 | 496 | } |
|
497 | 497 | |
|
498 | 498 | .tabular label.inline{ |
|
499 | 499 | font-weight: normal; |
|
500 | 500 | float:none; |
|
501 | 501 | margin-left: 5px !important; |
|
502 | 502 | width: auto; |
|
503 | 503 | } |
|
504 | 504 | |
|
505 | 505 | label.no-css { |
|
506 | 506 | font-weight: inherit; |
|
507 | 507 | float:none; |
|
508 | 508 | text-align:left; |
|
509 | 509 | margin-left:0px; |
|
510 | 510 | width:auto; |
|
511 | 511 | } |
|
512 | 512 | input#time_entry_comments { width: 90%;} |
|
513 | 513 | |
|
514 | 514 | #preview fieldset {margin-top: 1em; background: url(../images/draft.png)} |
|
515 | 515 | |
|
516 | 516 | .tabular.settings p{ padding-left: 300px; } |
|
517 | 517 | .tabular.settings label{ margin-left: -300px; width: 295px; } |
|
518 | 518 | .tabular.settings textarea { width: 99%; } |
|
519 | 519 | |
|
520 | 520 | .settings.enabled_scm table {width:100%} |
|
521 | 521 | .settings.enabled_scm td.scm_name{ font-weight: bold; } |
|
522 | 522 | |
|
523 | 523 | fieldset.settings label { display: block; } |
|
524 | 524 | fieldset#notified_events .parent { padding-left: 20px; } |
|
525 | 525 | |
|
526 | 526 | span.required {color: #bb0000;} |
|
527 | 527 | .summary {font-style: italic;} |
|
528 | 528 | |
|
529 | 529 | #attachments_fields input.description {margin-left:4px; width:340px;} |
|
530 | 530 | #attachments_fields span {display:block; white-space:nowrap;} |
|
531 | 531 | #attachments_fields input.filename {border:0; height:1.8em; width:250px; color:#555; background-color:inherit; background:url(../images/attachment.png) no-repeat 1px 50%; padding-left:18px;} |
|
532 | 532 | #attachments_fields .ajax-waiting input.filename {background:url(../images/hourglass.png) no-repeat 0px 50%;} |
|
533 | 533 | #attachments_fields .ajax-loading input.filename {background:url(../images/loading.gif) no-repeat 0px 50%;} |
|
534 | 534 | #attachments_fields div.ui-progressbar { width: 100px; height:14px; margin: 2px 0 -5px 8px; display: inline-block; } |
|
535 | 535 | a.remove-upload {background: url(../images/delete.png) no-repeat 1px 50%; width:1px; display:inline-block; padding-left:16px;} |
|
536 | 536 | a.remove-upload:hover {text-decoration:none !important;} |
|
537 | 537 | |
|
538 | 538 | div.fileover { background-color: lavender; } |
|
539 | 539 | |
|
540 | 540 | div.attachments { margin-top: 12px; } |
|
541 | 541 | div.attachments p { margin:4px 0 2px 0; } |
|
542 | 542 | div.attachments img { vertical-align: middle; } |
|
543 | 543 | div.attachments span.author { font-size: 0.9em; color: #888; } |
|
544 | 544 | |
|
545 | 545 | div.thumbnails {margin-top:0.6em;} |
|
546 | 546 | div.thumbnails div {background:#fff;border:2px solid #ddd;display:inline-block;margin-right:2px;} |
|
547 | 547 | div.thumbnails img {margin: 3px;} |
|
548 | 548 | |
|
549 | 549 | p.other-formats { text-align: right; font-size:0.9em; color: #666; } |
|
550 | 550 | .other-formats span + span:before { content: "| "; } |
|
551 | 551 | |
|
552 | 552 | a.atom { background: url(../images/feed.png) no-repeat 1px 50%; padding: 2px 0px 3px 16px; } |
|
553 | 553 | |
|
554 | 554 | em.info {font-style:normal;font-size:90%;color:#888;display:block;} |
|
555 | 555 | em.info.error {padding-left:20px; background:url(../images/exclamation.png) no-repeat 0 50%;} |
|
556 | 556 | |
|
557 | 557 | textarea.text_cf {width:90%;} |
|
558 | 558 | |
|
559 | 559 | /* Project members tab */ |
|
560 | 560 | div#tab-content-members .splitcontentleft, div#tab-content-memberships .splitcontentleft, div#tab-content-users .splitcontentleft { width: 64% } |
|
561 | 561 | div#tab-content-members .splitcontentright, div#tab-content-memberships .splitcontentright, div#tab-content-users .splitcontentright { width: 34% } |
|
562 | 562 | div#tab-content-members fieldset, div#tab-content-memberships fieldset, div#tab-content-users fieldset { padding:1em; margin-bottom: 1em; } |
|
563 | 563 | div#tab-content-members fieldset legend, div#tab-content-memberships fieldset legend, div#tab-content-users fieldset legend { font-weight: bold; } |
|
564 | 564 | div#tab-content-members fieldset label, div#tab-content-memberships fieldset label, div#tab-content-users fieldset label { display: block; } |
|
565 |
div#tab-content-members |
|
|
565 | div#tab-content-members #principals, div#tab-content-users #principals { max-height: 400px; overflow:auto; } | |
|
566 | 566 | |
|
567 | 567 | #users_for_watcher {height: 200px; overflow:auto;} |
|
568 | 568 | #users_for_watcher label {display: block;} |
|
569 | 569 | |
|
570 | 570 | table.members td.group { padding-left: 20px; background: url(../images/group.png) no-repeat 0% 50%; } |
|
571 | 571 | |
|
572 | 572 | input#principal_search, input#user_search {width:90%} |
|
573 | 573 | |
|
574 | 574 | input.autocomplete { |
|
575 | 575 | background: #fff url(../images/magnifier.png) no-repeat 2px 50%; padding-left:20px; |
|
576 | 576 | border:1px solid #9EB1C2; border-radius:2px; height:1.5em; |
|
577 | 577 | } |
|
578 | 578 | input.autocomplete.ajax-loading { |
|
579 | 579 | background-image: url(../images/loading.gif); |
|
580 | 580 | } |
|
581 | 581 | |
|
582 | 582 | * html div#tab-content-members fieldset div { height: 450px; } |
|
583 | 583 | |
|
584 | 584 | /***** Flash & error messages ****/ |
|
585 | 585 | #errorExplanation, div.flash, .nodata, .warning, .conflict { |
|
586 | 586 | padding: 4px 4px 4px 30px; |
|
587 | 587 | margin-bottom: 12px; |
|
588 | 588 | font-size: 1.1em; |
|
589 | 589 | border: 2px solid; |
|
590 | 590 | } |
|
591 | 591 | |
|
592 | 592 | div.flash {margin-top: 8px;} |
|
593 | 593 | |
|
594 | 594 | div.flash.error, #errorExplanation { |
|
595 | 595 | background: url(../images/exclamation.png) 8px 50% no-repeat; |
|
596 | 596 | background-color: #ffe3e3; |
|
597 | 597 | border-color: #dd0000; |
|
598 | 598 | color: #880000; |
|
599 | 599 | } |
|
600 | 600 | |
|
601 | 601 | div.flash.notice { |
|
602 | 602 | background: url(../images/true.png) 8px 5px no-repeat; |
|
603 | 603 | background-color: #dfffdf; |
|
604 | 604 | border-color: #9fcf9f; |
|
605 | 605 | color: #005f00; |
|
606 | 606 | } |
|
607 | 607 | |
|
608 | 608 | div.flash.warning, .conflict { |
|
609 | 609 | background: url(../images/warning.png) 8px 5px no-repeat; |
|
610 | 610 | background-color: #FFEBC1; |
|
611 | 611 | border-color: #FDBF3B; |
|
612 | 612 | color: #A6750C; |
|
613 | 613 | text-align: left; |
|
614 | 614 | } |
|
615 | 615 | |
|
616 | 616 | .nodata, .warning { |
|
617 | 617 | text-align: center; |
|
618 | 618 | background-color: #FFEBC1; |
|
619 | 619 | border-color: #FDBF3B; |
|
620 | 620 | color: #A6750C; |
|
621 | 621 | } |
|
622 | 622 | |
|
623 | 623 | #errorExplanation ul { font-size: 0.9em;} |
|
624 | 624 | #errorExplanation h2, #errorExplanation p { display: none; } |
|
625 | 625 | |
|
626 | 626 | .conflict-details {font-size:80%;} |
|
627 | 627 | |
|
628 | 628 | /***** Ajax indicator ******/ |
|
629 | 629 | #ajax-indicator { |
|
630 | 630 | position: absolute; /* fixed not supported by IE */ |
|
631 | 631 | background-color:#eee; |
|
632 | 632 | border: 1px solid #bbb; |
|
633 | 633 | top:35%; |
|
634 | 634 | left:40%; |
|
635 | 635 | width:20%; |
|
636 | 636 | font-weight:bold; |
|
637 | 637 | text-align:center; |
|
638 | 638 | padding:0.6em; |
|
639 | 639 | z-index:100; |
|
640 | 640 | opacity: 0.5; |
|
641 | 641 | } |
|
642 | 642 | |
|
643 | 643 | html>body #ajax-indicator { position: fixed; } |
|
644 | 644 | |
|
645 | 645 | #ajax-indicator span { |
|
646 | 646 | background-position: 0% 40%; |
|
647 | 647 | background-repeat: no-repeat; |
|
648 | 648 | background-image: url(../images/loading.gif); |
|
649 | 649 | padding-left: 26px; |
|
650 | 650 | vertical-align: bottom; |
|
651 | 651 | } |
|
652 | 652 | |
|
653 | 653 | /***** Calendar *****/ |
|
654 | 654 | table.cal {border-collapse: collapse; width: 100%; margin: 0px 0 6px 0;border: 1px solid #d7d7d7;} |
|
655 | 655 | table.cal thead th {width: 14%; background-color:#EEEEEE; padding: 4px; } |
|
656 | 656 | table.cal thead th.week-number {width: auto;} |
|
657 | 657 | table.cal tbody tr {height: 100px;} |
|
658 | 658 | table.cal td {border: 1px solid #d7d7d7; vertical-align: top; font-size: 0.9em;} |
|
659 | 659 | table.cal td.week-number { background-color:#EEEEEE; padding: 4px; border:none; font-size: 1em;} |
|
660 | 660 | table.cal td p.day-num {font-size: 1.1em; text-align:right;} |
|
661 | 661 | table.cal td.odd p.day-num {color: #bbb;} |
|
662 | 662 | table.cal td.today {background:#ffffdd;} |
|
663 | 663 | table.cal td.today p.day-num {font-weight: bold;} |
|
664 | 664 | table.cal .starting a, p.cal.legend .starting {background: url(../images/bullet_go.png) no-repeat -1px -2px; padding-left:16px;} |
|
665 | 665 | table.cal .ending a, p.cal.legend .ending {background: url(../images/bullet_end.png) no-repeat -1px -2px; padding-left:16px;} |
|
666 | 666 | table.cal .starting.ending a, p.cal.legend .starting.ending {background: url(../images/bullet_diamond.png) no-repeat -1px -2px; padding-left:16px;} |
|
667 | 667 | p.cal.legend span {display:block;} |
|
668 | 668 | |
|
669 | 669 | /***** Tooltips ******/ |
|
670 | 670 | .tooltip{position:relative;z-index:24;} |
|
671 | 671 | .tooltip:hover{z-index:25;color:#000;} |
|
672 | 672 | .tooltip span.tip{display: none; text-align:left;} |
|
673 | 673 | |
|
674 | 674 | div.tooltip:hover span.tip{ |
|
675 | 675 | display:block; |
|
676 | 676 | position:absolute; |
|
677 | 677 | top:12px; left:24px; width:270px; |
|
678 | 678 | border:1px solid #555; |
|
679 | 679 | background-color:#fff; |
|
680 | 680 | padding: 4px; |
|
681 | 681 | font-size: 0.8em; |
|
682 | 682 | color:#505050; |
|
683 | 683 | } |
|
684 | 684 | |
|
685 | 685 | img.ui-datepicker-trigger { |
|
686 | 686 | cursor: pointer; |
|
687 | 687 | vertical-align: middle; |
|
688 | 688 | margin-left: 4px; |
|
689 | 689 | } |
|
690 | 690 | |
|
691 | 691 | /***** Progress bar *****/ |
|
692 | 692 | table.progress { |
|
693 | 693 | border-collapse: collapse; |
|
694 | 694 | border-spacing: 0pt; |
|
695 | 695 | empty-cells: show; |
|
696 | 696 | text-align: center; |
|
697 | 697 | float:left; |
|
698 | 698 | margin: 1px 6px 1px 0px; |
|
699 | 699 | } |
|
700 | 700 | |
|
701 | 701 | table.progress td { height: 1em; } |
|
702 | 702 | table.progress td.closed { background: #BAE0BA none repeat scroll 0%; } |
|
703 | 703 | table.progress td.done { background: #D3EDD3 none repeat scroll 0%; } |
|
704 | 704 | table.progress td.todo { background: #eee none repeat scroll 0%; } |
|
705 | 705 | p.percent {font-size: 80%;} |
|
706 | 706 | p.progress-info {clear: left; font-size: 80%; margin-top:-4px; color:#777;} |
|
707 | 707 | |
|
708 | 708 | #roadmap table.progress td { height: 1.2em; } |
|
709 | 709 | /***** Tabs *****/ |
|
710 | 710 | #content .tabs {height: 2.6em; margin-bottom:1.2em; position:relative; overflow:hidden;} |
|
711 | 711 | #content .tabs ul {margin:0; position:absolute; bottom:0; padding-left:0.5em; width: 2000px; border-bottom: 1px solid #bbbbbb;} |
|
712 | 712 | #content .tabs ul li { |
|
713 | 713 | float:left; |
|
714 | 714 | list-style-type:none; |
|
715 | 715 | white-space:nowrap; |
|
716 | 716 | margin-right:4px; |
|
717 | 717 | background:#fff; |
|
718 | 718 | position:relative; |
|
719 | 719 | margin-bottom:-1px; |
|
720 | 720 | } |
|
721 | 721 | #content .tabs ul li a{ |
|
722 | 722 | display:block; |
|
723 | 723 | font-size: 0.9em; |
|
724 | 724 | text-decoration:none; |
|
725 | 725 | line-height:1.3em; |
|
726 | 726 | padding:4px 6px 4px 6px; |
|
727 | 727 | border: 1px solid #ccc; |
|
728 | 728 | border-bottom: 1px solid #bbbbbb; |
|
729 | 729 | background-color: #f6f6f6; |
|
730 | 730 | color:#999; |
|
731 | 731 | font-weight:bold; |
|
732 | 732 | border-top-left-radius:3px; |
|
733 | 733 | border-top-right-radius:3px; |
|
734 | 734 | } |
|
735 | 735 | |
|
736 | 736 | #content .tabs ul li a:hover { |
|
737 | 737 | background-color: #ffffdd; |
|
738 | 738 | text-decoration:none; |
|
739 | 739 | } |
|
740 | 740 | |
|
741 | 741 | #content .tabs ul li a.selected { |
|
742 | 742 | background-color: #fff; |
|
743 | 743 | border: 1px solid #bbbbbb; |
|
744 | 744 | border-bottom: 1px solid #fff; |
|
745 | 745 | color:#444; |
|
746 | 746 | } |
|
747 | 747 | |
|
748 | 748 | #content .tabs ul li a.selected:hover {background-color: #fff;} |
|
749 | 749 | |
|
750 | 750 | div.tabs-buttons { position:absolute; right: 0; width: 48px; height: 24px; background: white; bottom: 0; border-bottom: 1px solid #bbbbbb; } |
|
751 | 751 | |
|
752 | 752 | button.tab-left, button.tab-right { |
|
753 | 753 | font-size: 0.9em; |
|
754 | 754 | cursor: pointer; |
|
755 | 755 | height:24px; |
|
756 | 756 | border: 1px solid #ccc; |
|
757 | 757 | border-bottom: 1px solid #bbbbbb; |
|
758 | 758 | position:absolute; |
|
759 | 759 | padding:4px; |
|
760 | 760 | width: 20px; |
|
761 | 761 | bottom: -1px; |
|
762 | 762 | } |
|
763 | 763 | |
|
764 | 764 | button.tab-left { |
|
765 | 765 | right: 20px; |
|
766 | 766 | background: #eeeeee url(../images/bullet_arrow_left.png) no-repeat 50% 50%; |
|
767 | 767 | border-top-left-radius:3px; |
|
768 | 768 | } |
|
769 | 769 | |
|
770 | 770 | button.tab-right { |
|
771 | 771 | right: 0; |
|
772 | 772 | background: #eeeeee url(../images/bullet_arrow_right.png) no-repeat 50% 50%; |
|
773 | 773 | border-top-right-radius:3px; |
|
774 | 774 | } |
|
775 | 775 | |
|
776 | 776 | /***** Diff *****/ |
|
777 | 777 | .diff_out { background: #fcc; } |
|
778 | 778 | .diff_out span { background: #faa; } |
|
779 | 779 | .diff_in { background: #cfc; } |
|
780 | 780 | .diff_in span { background: #afa; } |
|
781 | 781 | |
|
782 | 782 | .text-diff { |
|
783 | 783 | padding: 1em; |
|
784 | 784 | background-color:#f6f6f6; |
|
785 | 785 | color:#505050; |
|
786 | 786 | border: 1px solid #e4e4e4; |
|
787 | 787 | } |
|
788 | 788 | |
|
789 | 789 | /***** Wiki *****/ |
|
790 | 790 | div.wiki table { |
|
791 | 791 | border-collapse: collapse; |
|
792 | 792 | margin-bottom: 1em; |
|
793 | 793 | } |
|
794 | 794 | |
|
795 | 795 | div.wiki table, div.wiki td, div.wiki th { |
|
796 | 796 | border: 1px solid #bbb; |
|
797 | 797 | padding: 4px; |
|
798 | 798 | } |
|
799 | 799 | |
|
800 | 800 | div.wiki .noborder, div.wiki .noborder td, div.wiki .noborder th {border:0;} |
|
801 | 801 | |
|
802 | 802 | div.wiki .external { |
|
803 | 803 | background-position: 0% 60%; |
|
804 | 804 | background-repeat: no-repeat; |
|
805 | 805 | padding-left: 12px; |
|
806 | 806 | background-image: url(../images/external.png); |
|
807 | 807 | } |
|
808 | 808 | |
|
809 | 809 | div.wiki a.new {color: #b73535;} |
|
810 | 810 | |
|
811 | 811 | div.wiki ul, div.wiki ol {margin-bottom:1em;} |
|
812 | 812 | |
|
813 | 813 | div.wiki pre { |
|
814 | 814 | margin: 1em 1em 1em 1.6em; |
|
815 | 815 | padding: 8px; |
|
816 | 816 | background-color: #fafafa; |
|
817 | 817 | border: 1px solid #e2e2e2; |
|
818 | 818 | width:auto; |
|
819 | 819 | overflow-x: auto; |
|
820 | 820 | overflow-y: hidden; |
|
821 | 821 | } |
|
822 | 822 | |
|
823 | 823 | div.wiki ul.toc { |
|
824 | 824 | background-color: #ffffdd; |
|
825 | 825 | border: 1px solid #e4e4e4; |
|
826 | 826 | padding: 4px; |
|
827 | 827 | line-height: 1.2em; |
|
828 | 828 | margin-bottom: 12px; |
|
829 | 829 | margin-right: 12px; |
|
830 | 830 | margin-left: 0; |
|
831 | 831 | display: table |
|
832 | 832 | } |
|
833 | 833 | * html div.wiki ul.toc { width: 50%; } /* IE6 doesn't autosize div */ |
|
834 | 834 | |
|
835 | 835 | div.wiki ul.toc.right { float: right; margin-left: 12px; margin-right: 0; width: auto; } |
|
836 | 836 | div.wiki ul.toc.left { float: left; margin-right: 12px; margin-left: 0; width: auto; } |
|
837 | 837 | div.wiki ul.toc ul { margin: 0; padding: 0; } |
|
838 | 838 | div.wiki ul.toc li {list-style-type:none; margin: 0; font-size:12px;} |
|
839 | 839 | div.wiki ul.toc li li {margin-left: 1.5em; font-size:10px;} |
|
840 | 840 | div.wiki ul.toc a { |
|
841 | 841 | font-size: 0.9em; |
|
842 | 842 | font-weight: normal; |
|
843 | 843 | text-decoration: none; |
|
844 | 844 | color: #606060; |
|
845 | 845 | } |
|
846 | 846 | div.wiki ul.toc a:hover { color: #c61a1a; text-decoration: underline;} |
|
847 | 847 | |
|
848 | 848 | a.wiki-anchor { display: none; margin-left: 6px; text-decoration: none; } |
|
849 | 849 | a.wiki-anchor:hover { color: #aaa !important; text-decoration: none; } |
|
850 | 850 | h1:hover a.wiki-anchor, h2:hover a.wiki-anchor, h3:hover a.wiki-anchor { display: inline; color: #ddd; } |
|
851 | 851 | |
|
852 | 852 | div.wiki img { vertical-align: middle; } |
|
853 | 853 | |
|
854 | 854 | /***** My page layout *****/ |
|
855 | 855 | .block-receiver { |
|
856 | 856 | border:1px dashed #c0c0c0; |
|
857 | 857 | margin-bottom: 20px; |
|
858 | 858 | padding: 15px 0 15px 0; |
|
859 | 859 | } |
|
860 | 860 | |
|
861 | 861 | .mypage-box { |
|
862 | 862 | margin:0 0 20px 0; |
|
863 | 863 | color:#505050; |
|
864 | 864 | line-height:1.5em; |
|
865 | 865 | } |
|
866 | 866 | |
|
867 | 867 | .handle {cursor: move;} |
|
868 | 868 | |
|
869 | 869 | a.close-icon { |
|
870 | 870 | display:block; |
|
871 | 871 | margin-top:3px; |
|
872 | 872 | overflow:hidden; |
|
873 | 873 | width:12px; |
|
874 | 874 | height:12px; |
|
875 | 875 | background-repeat: no-repeat; |
|
876 | 876 | cursor:pointer; |
|
877 | 877 | background-image:url('../images/close.png'); |
|
878 | 878 | } |
|
879 | 879 | a.close-icon:hover {background-image:url('../images/close_hl.png');} |
|
880 | 880 | |
|
881 | 881 | /***** Gantt chart *****/ |
|
882 | 882 | .gantt_hdr { |
|
883 | 883 | position:absolute; |
|
884 | 884 | top:0; |
|
885 | 885 | height:16px; |
|
886 | 886 | border-top: 1px solid #c0c0c0; |
|
887 | 887 | border-bottom: 1px solid #c0c0c0; |
|
888 | 888 | border-right: 1px solid #c0c0c0; |
|
889 | 889 | text-align: center; |
|
890 | 890 | overflow: hidden; |
|
891 | 891 | } |
|
892 | 892 | |
|
893 | 893 | .gantt_hdr.nwday {background-color:#f1f1f1;} |
|
894 | 894 | |
|
895 | 895 | .gantt_subjects { font-size: 0.8em; } |
|
896 | 896 | .gantt_subjects div { line-height:16px;height:16px;overflow:hidden;white-space:nowrap;text-overflow: ellipsis; } |
|
897 | 897 | |
|
898 | 898 | .task { |
|
899 | 899 | position: absolute; |
|
900 | 900 | height:8px; |
|
901 | 901 | font-size:0.8em; |
|
902 | 902 | color:#888; |
|
903 | 903 | padding:0; |
|
904 | 904 | margin:0; |
|
905 | 905 | line-height:16px; |
|
906 | 906 | white-space:nowrap; |
|
907 | 907 | } |
|
908 | 908 | |
|
909 | 909 | .task.label {width:100%;} |
|
910 | 910 | .task.label.project, .task.label.version { font-weight: bold; } |
|
911 | 911 | |
|
912 | 912 | .task_late { background:#f66 url(../images/task_late.png); border: 1px solid #f66; } |
|
913 | 913 | .task_done { background:#00c600 url(../images/task_done.png); border: 1px solid #00c600; } |
|
914 | 914 | .task_todo { background:#aaa url(../images/task_todo.png); border: 1px solid #aaa; } |
|
915 | 915 | |
|
916 | 916 | .task_todo.parent { background: #888; border: 1px solid #888; height: 3px;} |
|
917 | 917 | .task_late.parent, .task_done.parent { height: 3px;} |
|
918 | 918 | .task.parent.marker.starting { position: absolute; background: url(../images/task_parent_end.png) no-repeat 0 0; width: 8px; height: 16px; margin-left: -4px; left: 0px; top: -1px;} |
|
919 | 919 | .task.parent.marker.ending { position: absolute; background: url(../images/task_parent_end.png) no-repeat 0 0; width: 8px; height: 16px; margin-left: -4px; right: 0px; top: -1px;} |
|
920 | 920 | |
|
921 | 921 | .version.task_late { background:#f66 url(../images/milestone_late.png); border: 1px solid #f66; height: 2px; margin-top: 3px;} |
|
922 | 922 | .version.task_done { background:#00c600 url(../images/milestone_done.png); border: 1px solid #00c600; height: 2px; margin-top: 3px;} |
|
923 | 923 | .version.task_todo { background:#fff url(../images/milestone_todo.png); border: 1px solid #fff; height: 2px; margin-top: 3px;} |
|
924 | 924 | .version.marker { background-image:url(../images/version_marker.png); background-repeat: no-repeat; border: 0; margin-left: -4px; margin-top: 1px; } |
|
925 | 925 | |
|
926 | 926 | .project.task_late { background:#f66 url(../images/milestone_late.png); border: 1px solid #f66; height: 2px; margin-top: 3px;} |
|
927 | 927 | .project.task_done { background:#00c600 url(../images/milestone_done.png); border: 1px solid #00c600; height: 2px; margin-top: 3px;} |
|
928 | 928 | .project.task_todo { background:#fff url(../images/milestone_todo.png); border: 1px solid #fff; height: 2px; margin-top: 3px;} |
|
929 | 929 | .project.marker { background-image:url(../images/project_marker.png); background-repeat: no-repeat; border: 0; margin-left: -4px; margin-top: 1px; } |
|
930 | 930 | |
|
931 | 931 | .version-behind-schedule a, .issue-behind-schedule a {color: #f66914;} |
|
932 | 932 | .version-overdue a, .issue-overdue a, .project-overdue a {color: #f00;} |
|
933 | 933 | |
|
934 | 934 | /***** Icons *****/ |
|
935 | 935 | .icon { |
|
936 | 936 | background-position: 0% 50%; |
|
937 | 937 | background-repeat: no-repeat; |
|
938 | 938 | padding-left: 20px; |
|
939 | 939 | padding-top: 2px; |
|
940 | 940 | padding-bottom: 3px; |
|
941 | 941 | } |
|
942 | 942 | |
|
943 | 943 | .icon-add { background-image: url(../images/add.png); } |
|
944 | 944 | .icon-edit { background-image: url(../images/edit.png); } |
|
945 | 945 | .icon-copy { background-image: url(../images/copy.png); } |
|
946 | 946 | .icon-duplicate { background-image: url(../images/duplicate.png); } |
|
947 | 947 | .icon-del { background-image: url(../images/delete.png); } |
|
948 | 948 | .icon-move { background-image: url(../images/move.png); } |
|
949 | 949 | .icon-save { background-image: url(../images/save.png); } |
|
950 | 950 | .icon-cancel { background-image: url(../images/cancel.png); } |
|
951 | 951 | .icon-multiple { background-image: url(../images/table_multiple.png); } |
|
952 | 952 | .icon-folder { background-image: url(../images/folder.png); } |
|
953 | 953 | .open .icon-folder { background-image: url(../images/folder_open.png); } |
|
954 | 954 | .icon-package { background-image: url(../images/package.png); } |
|
955 | 955 | .icon-user { background-image: url(../images/user.png); } |
|
956 | 956 | .icon-projects { background-image: url(../images/projects.png); } |
|
957 | 957 | .icon-help { background-image: url(../images/help.png); } |
|
958 | 958 | .icon-attachment { background-image: url(../images/attachment.png); } |
|
959 | 959 | .icon-history { background-image: url(../images/history.png); } |
|
960 | 960 | .icon-time { background-image: url(../images/time.png); } |
|
961 | 961 | .icon-time-add { background-image: url(../images/time_add.png); } |
|
962 | 962 | .icon-stats { background-image: url(../images/stats.png); } |
|
963 | 963 | .icon-warning { background-image: url(../images/warning.png); } |
|
964 | 964 | .icon-fav { background-image: url(../images/fav.png); } |
|
965 | 965 | .icon-fav-off { background-image: url(../images/fav_off.png); } |
|
966 | 966 | .icon-reload { background-image: url(../images/reload.png); } |
|
967 | 967 | .icon-lock { background-image: url(../images/locked.png); } |
|
968 | 968 | .icon-unlock { background-image: url(../images/unlock.png); } |
|
969 | 969 | .icon-checked { background-image: url(../images/true.png); } |
|
970 | 970 | .icon-details { background-image: url(../images/zoom_in.png); } |
|
971 | 971 | .icon-report { background-image: url(../images/report.png); } |
|
972 | 972 | .icon-comment { background-image: url(../images/comment.png); } |
|
973 | 973 | .icon-summary { background-image: url(../images/lightning.png); } |
|
974 | 974 | .icon-server-authentication { background-image: url(../images/server_key.png); } |
|
975 | 975 | .icon-issue { background-image: url(../images/ticket.png); } |
|
976 | 976 | .icon-zoom-in { background-image: url(../images/zoom_in.png); } |
|
977 | 977 | .icon-zoom-out { background-image: url(../images/zoom_out.png); } |
|
978 | 978 | .icon-passwd { background-image: url(../images/textfield_key.png); } |
|
979 | 979 | .icon-test { background-image: url(../images/bullet_go.png); } |
|
980 | 980 | |
|
981 | 981 | .icon-file { background-image: url(../images/files/default.png); } |
|
982 | 982 | .icon-file.text-plain { background-image: url(../images/files/text.png); } |
|
983 | 983 | .icon-file.text-x-c { background-image: url(../images/files/c.png); } |
|
984 | 984 | .icon-file.text-x-csharp { background-image: url(../images/files/csharp.png); } |
|
985 | 985 | .icon-file.text-x-java { background-image: url(../images/files/java.png); } |
|
986 | 986 | .icon-file.text-x-javascript { background-image: url(../images/files/js.png); } |
|
987 | 987 | .icon-file.text-x-php { background-image: url(../images/files/php.png); } |
|
988 | 988 | .icon-file.text-x-ruby { background-image: url(../images/files/ruby.png); } |
|
989 | 989 | .icon-file.text-xml { background-image: url(../images/files/xml.png); } |
|
990 | 990 | .icon-file.text-css { background-image: url(../images/files/css.png); } |
|
991 | 991 | .icon-file.text-html { background-image: url(../images/files/html.png); } |
|
992 | 992 | .icon-file.image-gif { background-image: url(../images/files/image.png); } |
|
993 | 993 | .icon-file.image-jpeg { background-image: url(../images/files/image.png); } |
|
994 | 994 | .icon-file.image-png { background-image: url(../images/files/image.png); } |
|
995 | 995 | .icon-file.image-tiff { background-image: url(../images/files/image.png); } |
|
996 | 996 | .icon-file.application-pdf { background-image: url(../images/files/pdf.png); } |
|
997 | 997 | .icon-file.application-zip { background-image: url(../images/files/zip.png); } |
|
998 | 998 | .icon-file.application-x-gzip { background-image: url(../images/files/zip.png); } |
|
999 | 999 | |
|
1000 | 1000 | img.gravatar { |
|
1001 | 1001 | padding: 2px; |
|
1002 | 1002 | border: solid 1px #d5d5d5; |
|
1003 | 1003 | background: #fff; |
|
1004 | 1004 | vertical-align: middle; |
|
1005 | 1005 | } |
|
1006 | 1006 | |
|
1007 | 1007 | div.issue img.gravatar { |
|
1008 | 1008 | float: left; |
|
1009 | 1009 | margin: 0 6px 0 0; |
|
1010 | 1010 | padding: 5px; |
|
1011 | 1011 | } |
|
1012 | 1012 | |
|
1013 | 1013 | div.issue table img.gravatar { |
|
1014 | 1014 | height: 14px; |
|
1015 | 1015 | width: 14px; |
|
1016 | 1016 | padding: 2px; |
|
1017 | 1017 | float: left; |
|
1018 | 1018 | margin: 0 0.5em 0 0; |
|
1019 | 1019 | } |
|
1020 | 1020 | |
|
1021 | 1021 | h2 img.gravatar {margin: -2px 4px -4px 0;} |
|
1022 | 1022 | h3 img.gravatar {margin: -4px 4px -4px 0;} |
|
1023 | 1023 | h4 img.gravatar {margin: -6px 4px -4px 0;} |
|
1024 | 1024 | td.username img.gravatar {margin: 0 0.5em 0 0; vertical-align: top;} |
|
1025 | 1025 | #activity dt img.gravatar {float: left; margin: 0 1em 1em 0;} |
|
1026 | 1026 | /* Used on 12px Gravatar img tags without the icon background */ |
|
1027 | 1027 | .icon-gravatar {float: left; margin-right: 4px;} |
|
1028 | 1028 | |
|
1029 | 1029 | #activity dt, .journal {clear: left;} |
|
1030 | 1030 | |
|
1031 | 1031 | .journal-link {float: right;} |
|
1032 | 1032 | |
|
1033 | 1033 | h2 img { vertical-align:middle; } |
|
1034 | 1034 | |
|
1035 | 1035 | .hascontextmenu { cursor: context-menu; } |
|
1036 | 1036 | |
|
1037 | 1037 | /************* CodeRay styles *************/ |
|
1038 | 1038 | .syntaxhl div {display: inline;} |
|
1039 | 1039 | .syntaxhl .line-numbers {padding: 2px 4px 2px 4px; background-color: #eee; margin:0px 5px 0px 0px;} |
|
1040 | 1040 | .syntaxhl .code pre { overflow: auto } |
|
1041 | 1041 | .syntaxhl .debug { color: white !important; background: blue !important; } |
|
1042 | 1042 | |
|
1043 | 1043 | .syntaxhl .annotation { color:#007 } |
|
1044 | 1044 | .syntaxhl .attribute-name { color:#b48 } |
|
1045 | 1045 | .syntaxhl .attribute-value { color:#700 } |
|
1046 | 1046 | .syntaxhl .binary { color:#509 } |
|
1047 | 1047 | .syntaxhl .char .content { color:#D20 } |
|
1048 | 1048 | .syntaxhl .char .delimiter { color:#710 } |
|
1049 | 1049 | .syntaxhl .char { color:#D20 } |
|
1050 | 1050 | .syntaxhl .class { color:#258; font-weight:bold } |
|
1051 | 1051 | .syntaxhl .class-variable { color:#369 } |
|
1052 | 1052 | .syntaxhl .color { color:#0A0 } |
|
1053 | 1053 | .syntaxhl .comment { color:#385 } |
|
1054 | 1054 | .syntaxhl .comment .char { color:#385 } |
|
1055 | 1055 | .syntaxhl .comment .delimiter { color:#385 } |
|
1056 | 1056 | .syntaxhl .complex { color:#A08 } |
|
1057 | 1057 | .syntaxhl .constant { color:#258; font-weight:bold } |
|
1058 | 1058 | .syntaxhl .decorator { color:#B0B } |
|
1059 | 1059 | .syntaxhl .definition { color:#099; font-weight:bold } |
|
1060 | 1060 | .syntaxhl .delimiter { color:black } |
|
1061 | 1061 | .syntaxhl .directive { color:#088; font-weight:bold } |
|
1062 | 1062 | .syntaxhl .doc { color:#970 } |
|
1063 | 1063 | .syntaxhl .doc-string { color:#D42; font-weight:bold } |
|
1064 | 1064 | .syntaxhl .doctype { color:#34b } |
|
1065 | 1065 | .syntaxhl .entity { color:#800; font-weight:bold } |
|
1066 | 1066 | .syntaxhl .error { color:#F00; background-color:#FAA } |
|
1067 | 1067 | .syntaxhl .escape { color:#666 } |
|
1068 | 1068 | .syntaxhl .exception { color:#C00; font-weight:bold } |
|
1069 | 1069 | .syntaxhl .float { color:#06D } |
|
1070 | 1070 | .syntaxhl .function { color:#06B; font-weight:bold } |
|
1071 | 1071 | .syntaxhl .global-variable { color:#d70 } |
|
1072 | 1072 | .syntaxhl .hex { color:#02b } |
|
1073 | 1073 | .syntaxhl .imaginary { color:#f00 } |
|
1074 | 1074 | .syntaxhl .include { color:#B44; font-weight:bold } |
|
1075 | 1075 | .syntaxhl .inline { background-color: hsla(0,0%,0%,0.07); color: black } |
|
1076 | 1076 | .syntaxhl .inline-delimiter { font-weight: bold; color: #666 } |
|
1077 | 1077 | .syntaxhl .instance-variable { color:#33B } |
|
1078 | 1078 | .syntaxhl .integer { color:#06D } |
|
1079 | 1079 | .syntaxhl .key .char { color: #60f } |
|
1080 | 1080 | .syntaxhl .key .delimiter { color: #404 } |
|
1081 | 1081 | .syntaxhl .key { color: #606 } |
|
1082 | 1082 | .syntaxhl .keyword { color:#939; font-weight:bold } |
|
1083 | 1083 | .syntaxhl .label { color:#970; font-weight:bold } |
|
1084 | 1084 | .syntaxhl .local-variable { color:#963 } |
|
1085 | 1085 | .syntaxhl .namespace { color:#707; font-weight:bold } |
|
1086 | 1086 | .syntaxhl .octal { color:#40E } |
|
1087 | 1087 | .syntaxhl .operator { } |
|
1088 | 1088 | .syntaxhl .predefined { color:#369; font-weight:bold } |
|
1089 | 1089 | .syntaxhl .predefined-constant { color:#069 } |
|
1090 | 1090 | .syntaxhl .predefined-type { color:#0a5; font-weight:bold } |
|
1091 | 1091 | .syntaxhl .preprocessor { color:#579 } |
|
1092 | 1092 | .syntaxhl .pseudo-class { color:#00C; font-weight:bold } |
|
1093 | 1093 | .syntaxhl .regexp .content { color:#808 } |
|
1094 | 1094 | .syntaxhl .regexp .delimiter { color:#404 } |
|
1095 | 1095 | .syntaxhl .regexp .modifier { color:#C2C } |
|
1096 | 1096 | .syntaxhl .regexp { background-color:hsla(300,100%,50%,0.06); } |
|
1097 | 1097 | .syntaxhl .reserved { color:#080; font-weight:bold } |
|
1098 | 1098 | .syntaxhl .shell .content { color:#2B2 } |
|
1099 | 1099 | .syntaxhl .shell .delimiter { color:#161 } |
|
1100 | 1100 | .syntaxhl .shell { background-color:hsla(120,100%,50%,0.06); } |
|
1101 | 1101 | .syntaxhl .string .char { color: #46a } |
|
1102 | 1102 | .syntaxhl .string .content { color: #46a } |
|
1103 | 1103 | .syntaxhl .string .delimiter { color: #46a } |
|
1104 | 1104 | .syntaxhl .string .modifier { color: #46a } |
|
1105 | 1105 | .syntaxhl .symbol .content { color:#d33 } |
|
1106 | 1106 | .syntaxhl .symbol .delimiter { color:#d33 } |
|
1107 | 1107 | .syntaxhl .symbol { color:#d33 } |
|
1108 | 1108 | .syntaxhl .tag { color:#070 } |
|
1109 | 1109 | .syntaxhl .type { color:#339; font-weight:bold } |
|
1110 | 1110 | .syntaxhl .value { color: #088; } |
|
1111 | 1111 | .syntaxhl .variable { color:#037 } |
|
1112 | 1112 | |
|
1113 | 1113 | .syntaxhl .insert { background: hsla(120,100%,50%,0.12) } |
|
1114 | 1114 | .syntaxhl .delete { background: hsla(0,100%,50%,0.12) } |
|
1115 | 1115 | .syntaxhl .change { color: #bbf; background: #007; } |
|
1116 | 1116 | .syntaxhl .head { color: #f8f; background: #505 } |
|
1117 | 1117 | .syntaxhl .head .filename { color: white; } |
|
1118 | 1118 | |
|
1119 | 1119 | .syntaxhl .delete .eyecatcher { background-color: hsla(0,100%,50%,0.2); border: 1px solid hsla(0,100%,45%,0.5); margin: -1px; border-bottom: none; border-top-left-radius: 5px; border-top-right-radius: 5px; } |
|
1120 | 1120 | .syntaxhl .insert .eyecatcher { background-color: hsla(120,100%,50%,0.2); border: 1px solid hsla(120,100%,25%,0.5); margin: -1px; border-top: none; border-bottom-left-radius: 5px; border-bottom-right-radius: 5px; } |
|
1121 | 1121 | |
|
1122 | 1122 | .syntaxhl .insert .insert { color: #0c0; background:transparent; font-weight:bold } |
|
1123 | 1123 | .syntaxhl .delete .delete { color: #c00; background:transparent; font-weight:bold } |
|
1124 | 1124 | .syntaxhl .change .change { color: #88f } |
|
1125 | 1125 | .syntaxhl .head .head { color: #f4f } |
|
1126 | 1126 | |
|
1127 | 1127 | /***** Media print specific styles *****/ |
|
1128 | 1128 | @media print { |
|
1129 | 1129 | #top-menu, #header, #main-menu, #sidebar, #footer, .contextual, .other-formats { display:none; } |
|
1130 | 1130 | #main { background: #fff; } |
|
1131 | 1131 | #content { width: 99%; margin: 0; padding: 0; border: 0; background: #fff; overflow: visible !important;} |
|
1132 | 1132 | #wiki_add_attachment { display:none; } |
|
1133 | 1133 | .hide-when-print { display: none; } |
|
1134 | 1134 | .autoscroll {overflow-x: visible;} |
|
1135 | 1135 | table.list {margin-top:0.5em;} |
|
1136 | 1136 | table.list th, table.list td {border: 1px solid #aaa;} |
|
1137 | 1137 | } |
|
1138 | 1138 | |
|
1139 | 1139 | /* Accessibility specific styles */ |
|
1140 | 1140 | .hidden-for-sighted { |
|
1141 | 1141 | position:absolute; |
|
1142 | 1142 | left:-10000px; |
|
1143 | 1143 | top:auto; |
|
1144 | 1144 | width:1px; |
|
1145 | 1145 | height:1px; |
|
1146 | 1146 | overflow:hidden; |
|
1147 | 1147 | } |
@@ -1,205 +1,202 | |||
|
1 | 1 | # Redmine - project management software |
|
2 | 2 | # Copyright (C) 2006-2013 Jean-Philippe Lang |
|
3 | 3 | # |
|
4 | 4 | # This program is free software; you can redistribute it and/or |
|
5 | 5 | # modify it under the terms of the GNU General Public License |
|
6 | 6 | # as published by the Free Software Foundation; either version 2 |
|
7 | 7 | # of the License, or (at your option) any later version. |
|
8 | 8 | # |
|
9 | 9 | # This program is distributed in the hope that it will be useful, |
|
10 | 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 | 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 | 12 | # GNU General Public License for more details. |
|
13 | 13 | # |
|
14 | 14 | # You should have received a copy of the GNU General Public License |
|
15 | 15 | # along with this program; if not, write to the Free Software |
|
16 | 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
17 | 17 | |
|
18 | 18 | require File.expand_path('../../test_helper', __FILE__) |
|
19 | 19 | |
|
20 | 20 | class GroupsControllerTest < ActionController::TestCase |
|
21 | 21 | fixtures :projects, :users, :members, :member_roles, :roles, :groups_users |
|
22 | 22 | |
|
23 | 23 | def setup |
|
24 | 24 | @request.session[:user_id] = 1 |
|
25 | 25 | end |
|
26 | 26 | |
|
27 | 27 | def test_index |
|
28 | 28 | get :index |
|
29 | 29 | assert_response :success |
|
30 | 30 | assert_template 'index' |
|
31 | 31 | end |
|
32 | 32 | |
|
33 | 33 | def test_show |
|
34 | 34 | get :show, :id => 10 |
|
35 | 35 | assert_response :success |
|
36 | 36 | assert_template 'show' |
|
37 | 37 | end |
|
38 | 38 | |
|
39 | 39 | def test_show_invalid_should_return_404 |
|
40 | 40 | get :show, :id => 99 |
|
41 | 41 | assert_response 404 |
|
42 | 42 | end |
|
43 | 43 | |
|
44 | 44 | def test_new |
|
45 | 45 | get :new |
|
46 | 46 | assert_response :success |
|
47 | 47 | assert_template 'new' |
|
48 | 48 | assert_select 'input[name=?]', 'group[name]' |
|
49 | 49 | end |
|
50 | 50 | |
|
51 | 51 | def test_create |
|
52 | 52 | assert_difference 'Group.count' do |
|
53 | 53 | post :create, :group => {:name => 'New group'} |
|
54 | 54 | end |
|
55 | 55 | assert_redirected_to '/groups' |
|
56 | 56 | group = Group.first(:order => 'id DESC') |
|
57 | 57 | assert_equal 'New group', group.name |
|
58 | 58 | assert_equal [], group.users |
|
59 | 59 | end |
|
60 | 60 | |
|
61 | 61 | def test_create_and_continue |
|
62 | 62 | assert_difference 'Group.count' do |
|
63 | 63 | post :create, :group => {:name => 'New group'}, :continue => 'Create and continue' |
|
64 | 64 | end |
|
65 | 65 | assert_redirected_to '/groups/new' |
|
66 | 66 | group = Group.first(:order => 'id DESC') |
|
67 | 67 | assert_equal 'New group', group.name |
|
68 | 68 | end |
|
69 | 69 | |
|
70 | 70 | def test_create_with_failure |
|
71 | 71 | assert_no_difference 'Group.count' do |
|
72 | 72 | post :create, :group => {:name => ''} |
|
73 | 73 | end |
|
74 | 74 | assert_response :success |
|
75 | 75 | assert_template 'new' |
|
76 | 76 | end |
|
77 | 77 | |
|
78 | 78 | def test_edit |
|
79 | 79 | get :edit, :id => 10 |
|
80 | 80 | assert_response :success |
|
81 | 81 | assert_template 'edit' |
|
82 | 82 | |
|
83 | 83 | assert_select 'div#tab-content-users' |
|
84 | 84 | assert_select 'div#tab-content-memberships' do |
|
85 | 85 | assert_select 'a', :text => 'Private child of eCookbook' |
|
86 | 86 | end |
|
87 | 87 | end |
|
88 | 88 | |
|
89 | 89 | def test_update |
|
90 | 90 | new_name = 'New name' |
|
91 | 91 | put :update, :id => 10, :group => {:name => new_name} |
|
92 | 92 | assert_redirected_to '/groups' |
|
93 | 93 | group = Group.find(10) |
|
94 | 94 | assert_equal new_name, group.name |
|
95 | 95 | end |
|
96 | 96 | |
|
97 | 97 | def test_update_with_failure |
|
98 | 98 | put :update, :id => 10, :group => {:name => ''} |
|
99 | 99 | assert_response :success |
|
100 | 100 | assert_template 'edit' |
|
101 | 101 | end |
|
102 | 102 | |
|
103 | 103 | def test_destroy |
|
104 | 104 | assert_difference 'Group.count', -1 do |
|
105 | 105 | post :destroy, :id => 10 |
|
106 | 106 | end |
|
107 | 107 | assert_redirected_to '/groups' |
|
108 | 108 | end |
|
109 | 109 | |
|
110 | 110 | def test_add_users |
|
111 | 111 | assert_difference 'Group.find(10).users.count', 2 do |
|
112 | 112 | post :add_users, :id => 10, :user_ids => ['2', '3'] |
|
113 | 113 | end |
|
114 | 114 | end |
|
115 | 115 | |
|
116 | 116 | def test_xhr_add_users |
|
117 | 117 | assert_difference 'Group.find(10).users.count', 2 do |
|
118 | 118 | xhr :post, :add_users, :id => 10, :user_ids => ['2', '3'] |
|
119 | 119 | assert_response :success |
|
120 | 120 | assert_template 'add_users' |
|
121 | 121 | assert_equal 'text/javascript', response.content_type |
|
122 | 122 | end |
|
123 | 123 | assert_match /John Smith/, response.body |
|
124 | 124 | end |
|
125 | 125 | |
|
126 | 126 | def test_remove_user |
|
127 | 127 | assert_difference 'Group.find(10).users.count', -1 do |
|
128 | 128 | delete :remove_user, :id => 10, :user_id => '8' |
|
129 | 129 | end |
|
130 | 130 | end |
|
131 | 131 | |
|
132 | 132 | def test_xhr_remove_user |
|
133 | 133 | assert_difference 'Group.find(10).users.count', -1 do |
|
134 | 134 | xhr :delete, :remove_user, :id => 10, :user_id => '8' |
|
135 | 135 | assert_response :success |
|
136 | 136 | assert_template 'remove_user' |
|
137 | 137 | assert_equal 'text/javascript', response.content_type |
|
138 | 138 | end |
|
139 | 139 | end |
|
140 | 140 | |
|
141 | 141 | def test_new_membership |
|
142 | 142 | assert_difference 'Group.find(10).members.count' do |
|
143 | 143 | post :edit_membership, :id => 10, :membership => { :project_id => 2, :role_ids => ['1', '2']} |
|
144 | 144 | end |
|
145 | 145 | end |
|
146 | 146 | |
|
147 | 147 | def test_xhr_new_membership |
|
148 | 148 | assert_difference 'Group.find(10).members.count' do |
|
149 | 149 | xhr :post, :edit_membership, :id => 10, :membership => { :project_id => 2, :role_ids => ['1', '2']} |
|
150 | 150 | assert_response :success |
|
151 | 151 | assert_template 'edit_membership' |
|
152 | 152 | assert_equal 'text/javascript', response.content_type |
|
153 | 153 | end |
|
154 | 154 | assert_match /OnlineStore/, response.body |
|
155 | 155 | end |
|
156 | 156 | |
|
157 | 157 | def test_xhr_new_membership_with_failure |
|
158 | 158 | assert_no_difference 'Group.find(10).members.count' do |
|
159 | 159 | xhr :post, :edit_membership, :id => 10, :membership => { :project_id => 999, :role_ids => ['1', '2']} |
|
160 | 160 | assert_response :success |
|
161 | 161 | assert_template 'edit_membership' |
|
162 | 162 | assert_equal 'text/javascript', response.content_type |
|
163 | 163 | end |
|
164 | 164 | assert_match /alert/, response.body, "Alert message not sent" |
|
165 | 165 | end |
|
166 | 166 | |
|
167 | 167 | def test_edit_membership |
|
168 | 168 | assert_no_difference 'Group.find(10).members.count' do |
|
169 | 169 | post :edit_membership, :id => 10, :membership_id => 6, :membership => { :role_ids => ['1', '3']} |
|
170 | 170 | end |
|
171 | 171 | end |
|
172 | 172 | |
|
173 | 173 | def test_xhr_edit_membership |
|
174 | 174 | assert_no_difference 'Group.find(10).members.count' do |
|
175 | 175 | xhr :post, :edit_membership, :id => 10, :membership_id => 6, :membership => { :role_ids => ['1', '3']} |
|
176 | 176 | assert_response :success |
|
177 | 177 | assert_template 'edit_membership' |
|
178 | 178 | assert_equal 'text/javascript', response.content_type |
|
179 | 179 | end |
|
180 | 180 | end |
|
181 | 181 | |
|
182 | 182 | def test_destroy_membership |
|
183 | 183 | assert_difference 'Group.find(10).members.count', -1 do |
|
184 | 184 | post :destroy_membership, :id => 10, :membership_id => 6 |
|
185 | 185 | end |
|
186 | 186 | end |
|
187 | 187 | |
|
188 | 188 | def test_xhr_destroy_membership |
|
189 | 189 | assert_difference 'Group.find(10).members.count', -1 do |
|
190 | 190 | xhr :post, :destroy_membership, :id => 10, :membership_id => 6 |
|
191 | 191 | assert_response :success |
|
192 | 192 | assert_template 'destroy_membership' |
|
193 | 193 | assert_equal 'text/javascript', response.content_type |
|
194 | 194 | end |
|
195 | 195 | end |
|
196 | 196 | |
|
197 | 197 | def test_autocomplete_for_user |
|
198 | get :autocomplete_for_user, :id => 10, :q => 'mis' | |
|
198 | get :autocomplete_for_user, :id => 10, :q => 'smi', :format => 'js' | |
|
199 | 199 | assert_response :success |
|
200 | users = assigns(:users) | |
|
201 | assert_not_nil users | |
|
202 | assert users.any? | |
|
203 | assert !users.include?(Group.find(10).users.first) | |
|
200 | assert_include 'John Smith', response.body | |
|
204 | 201 | end |
|
205 | 202 | end |
@@ -1,114 +1,111 | |||
|
1 | 1 | # Redmine - project management software |
|
2 | 2 | # Copyright (C) 2006-2013 Jean-Philippe Lang |
|
3 | 3 | # |
|
4 | 4 | # This program is free software; you can redistribute it and/or |
|
5 | 5 | # modify it under the terms of the GNU General Public License |
|
6 | 6 | # as published by the Free Software Foundation; either version 2 |
|
7 | 7 | # of the License, or (at your option) any later version. |
|
8 | 8 | # |
|
9 | 9 | # This program is distributed in the hope that it will be useful, |
|
10 | 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 | 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 | 12 | # GNU General Public License for more details. |
|
13 | 13 | # |
|
14 | 14 | # You should have received a copy of the GNU General Public License |
|
15 | 15 | # along with this program; if not, write to the Free Software |
|
16 | 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
17 | 17 | |
|
18 | 18 | require File.expand_path('../../test_helper', __FILE__) |
|
19 | 19 | |
|
20 | 20 | class MembersControllerTest < ActionController::TestCase |
|
21 | 21 | fixtures :projects, :members, :member_roles, :roles, :users |
|
22 | 22 | |
|
23 | 23 | def setup |
|
24 | 24 | User.current = nil |
|
25 | 25 | @request.session[:user_id] = 2 |
|
26 | 26 | end |
|
27 | 27 | |
|
28 | 28 | def test_create |
|
29 | 29 | assert_difference 'Member.count' do |
|
30 | 30 | post :create, :project_id => 1, :membership => {:role_ids => [1], :user_id => 7} |
|
31 | 31 | end |
|
32 | 32 | assert_redirected_to '/projects/ecookbook/settings/members' |
|
33 | 33 | assert User.find(7).member_of?(Project.find(1)) |
|
34 | 34 | end |
|
35 | 35 | |
|
36 | 36 | def test_create_multiple |
|
37 | 37 | assert_difference 'Member.count', 3 do |
|
38 | 38 | post :create, :project_id => 1, :membership => {:role_ids => [1], :user_ids => [7, 8, 9]} |
|
39 | 39 | end |
|
40 | 40 | assert_redirected_to '/projects/ecookbook/settings/members' |
|
41 | 41 | assert User.find(7).member_of?(Project.find(1)) |
|
42 | 42 | end |
|
43 | 43 | |
|
44 | 44 | def test_xhr_create |
|
45 | 45 | assert_difference 'Member.count', 3 do |
|
46 | 46 | xhr :post, :create, :project_id => 1, :membership => {:role_ids => [1], :user_ids => [7, 8, 9]} |
|
47 | 47 | assert_response :success |
|
48 | 48 | assert_template 'create' |
|
49 | 49 | assert_equal 'text/javascript', response.content_type |
|
50 | 50 | end |
|
51 | 51 | assert User.find(7).member_of?(Project.find(1)) |
|
52 | 52 | assert User.find(8).member_of?(Project.find(1)) |
|
53 | 53 | assert User.find(9).member_of?(Project.find(1)) |
|
54 | 54 | assert_include 'tab-content-members', response.body |
|
55 | 55 | end |
|
56 | 56 | |
|
57 | 57 | def test_xhr_create_with_failure |
|
58 | 58 | assert_no_difference 'Member.count' do |
|
59 | 59 | xhr :post, :create, :project_id => 1, :membership => {:role_ids => [], :user_ids => [7, 8, 9]} |
|
60 | 60 | assert_response :success |
|
61 | 61 | assert_template 'create' |
|
62 | 62 | assert_equal 'text/javascript', response.content_type |
|
63 | 63 | end |
|
64 | 64 | assert_match /alert/, response.body, "Alert message not sent" |
|
65 | 65 | end |
|
66 | 66 | |
|
67 | 67 | def test_edit |
|
68 | 68 | assert_no_difference 'Member.count' do |
|
69 | 69 | put :update, :id => 2, :membership => {:role_ids => [1], :user_id => 3} |
|
70 | 70 | end |
|
71 | 71 | assert_redirected_to '/projects/ecookbook/settings/members' |
|
72 | 72 | end |
|
73 | 73 | |
|
74 | 74 | def test_xhr_edit |
|
75 | 75 | assert_no_difference 'Member.count' do |
|
76 | 76 | xhr :put, :update, :id => 2, :membership => {:role_ids => [1], :user_id => 3} |
|
77 | 77 | assert_response :success |
|
78 | 78 | assert_template 'update' |
|
79 | 79 | assert_equal 'text/javascript', response.content_type |
|
80 | 80 | end |
|
81 | 81 | member = Member.find(2) |
|
82 | 82 | assert_equal [1], member.role_ids |
|
83 | 83 | assert_equal 3, member.user_id |
|
84 | 84 | assert_include 'tab-content-members', response.body |
|
85 | 85 | end |
|
86 | 86 | |
|
87 | 87 | def test_destroy |
|
88 | 88 | assert_difference 'Member.count', -1 do |
|
89 | 89 | delete :destroy, :id => 2 |
|
90 | 90 | end |
|
91 | 91 | assert_redirected_to '/projects/ecookbook/settings/members' |
|
92 | 92 | assert !User.find(3).member_of?(Project.find(1)) |
|
93 | 93 | end |
|
94 | 94 | |
|
95 | 95 | def test_xhr_destroy |
|
96 | 96 | assert_difference 'Member.count', -1 do |
|
97 | 97 | xhr :delete, :destroy, :id => 2 |
|
98 | 98 | assert_response :success |
|
99 | 99 | assert_template 'destroy' |
|
100 | 100 | assert_equal 'text/javascript', response.content_type |
|
101 | 101 | end |
|
102 | 102 | assert_nil Member.find_by_id(2) |
|
103 | 103 | assert_include 'tab-content-members', response.body |
|
104 | 104 | end |
|
105 | 105 | |
|
106 | 106 | def test_autocomplete |
|
107 | get :autocomplete, :project_id => 1, :q => 'mis' | |
|
107 | get :autocomplete, :project_id => 1, :q => 'mis', :format => 'js' | |
|
108 | 108 | assert_response :success |
|
109 | assert_template 'autocomplete' | |
|
110 | ||
|
111 | assert_tag :label, :content => /User Misc/, | |
|
112 | :child => { :tag => 'input', :attributes => { :name => 'membership[user_ids][]', :value => '8' } } | |
|
109 | assert_include 'User Misc', response.body | |
|
113 | 110 | end |
|
114 | 111 | end |
@@ -1,102 +1,106 | |||
|
1 | 1 | # Redmine - project management software |
|
2 | 2 | # Copyright (C) 2006-2013 Jean-Philippe Lang |
|
3 | 3 | # |
|
4 | 4 | # This program is free software; you can redistribute it and/or |
|
5 | 5 | # modify it under the terms of the GNU General Public License |
|
6 | 6 | # as published by the Free Software Foundation; either version 2 |
|
7 | 7 | # of the License, or (at your option) any later version. |
|
8 | 8 | # |
|
9 | 9 | # This program is distributed in the hope that it will be useful, |
|
10 | 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 | 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 | 12 | # GNU General Public License for more details. |
|
13 | 13 | # |
|
14 | 14 | # You should have received a copy of the GNU General Public License |
|
15 | 15 | # along with this program; if not, write to the Free Software |
|
16 | 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
17 | 17 | |
|
18 | 18 | require File.expand_path('../../../test_helper', __FILE__) |
|
19 | 19 | |
|
20 | 20 | class RoutingGroupsTest < ActionController::IntegrationTest |
|
21 | 21 | def test_groups_resources |
|
22 | 22 | assert_routing( |
|
23 | 23 | { :method => 'get', :path => "/groups" }, |
|
24 | 24 | { :controller => 'groups', :action => 'index' } |
|
25 | 25 | ) |
|
26 | 26 | assert_routing( |
|
27 | 27 | { :method => 'get', :path => "/groups.xml" }, |
|
28 | 28 | { :controller => 'groups', :action => 'index', :format => 'xml' } |
|
29 | 29 | ) |
|
30 | 30 | assert_routing( |
|
31 | 31 | { :method => 'post', :path => "/groups" }, |
|
32 | 32 | { :controller => 'groups', :action => 'create' } |
|
33 | 33 | ) |
|
34 | 34 | assert_routing( |
|
35 | 35 | { :method => 'post', :path => "/groups.xml" }, |
|
36 | 36 | { :controller => 'groups', :action => 'create', :format => 'xml' } |
|
37 | 37 | ) |
|
38 | 38 | assert_routing( |
|
39 | 39 | { :method => 'get', :path => "/groups/new" }, |
|
40 | 40 | { :controller => 'groups', :action => 'new' } |
|
41 | 41 | ) |
|
42 | 42 | assert_routing( |
|
43 | 43 | { :method => 'get', :path => "/groups/1/edit" }, |
|
44 | 44 | { :controller => 'groups', :action => 'edit', :id => '1' } |
|
45 | 45 | ) |
|
46 | 46 | assert_routing( |
|
47 | 47 | { :method => 'get', :path => "/groups/1/autocomplete_for_user" }, |
|
48 | 48 | { :controller => 'groups', :action => 'autocomplete_for_user', :id => '1' } |
|
49 | 49 | ) |
|
50 | 50 | assert_routing( |
|
51 | { :method => 'get', :path => "/groups/1/autocomplete_for_user.js" }, | |
|
52 | { :controller => 'groups', :action => 'autocomplete_for_user', :id => '1', :format => 'js' } | |
|
53 | ) | |
|
54 | assert_routing( | |
|
51 | 55 | { :method => 'get', :path => "/groups/1" }, |
|
52 | 56 | { :controller => 'groups', :action => 'show', :id => '1' } |
|
53 | 57 | ) |
|
54 | 58 | assert_routing( |
|
55 | 59 | { :method => 'get', :path => "/groups/1.xml" }, |
|
56 | 60 | { :controller => 'groups', :action => 'show', :id => '1', :format => 'xml' } |
|
57 | 61 | ) |
|
58 | 62 | assert_routing( |
|
59 | 63 | { :method => 'put', :path => "/groups/1" }, |
|
60 | 64 | { :controller => 'groups', :action => 'update', :id => '1' } |
|
61 | 65 | ) |
|
62 | 66 | assert_routing( |
|
63 | 67 | { :method => 'put', :path => "/groups/1.xml" }, |
|
64 | 68 | { :controller => 'groups', :action => 'update', :id => '1', :format => 'xml' } |
|
65 | 69 | ) |
|
66 | 70 | assert_routing( |
|
67 | 71 | { :method => 'delete', :path => "/groups/1" }, |
|
68 | 72 | { :controller => 'groups', :action => 'destroy', :id => '1' } |
|
69 | 73 | ) |
|
70 | 74 | assert_routing( |
|
71 | 75 | { :method => 'delete', :path => "/groups/1.xml" }, |
|
72 | 76 | { :controller => 'groups', :action => 'destroy', :id => '1', :format => 'xml' } |
|
73 | 77 | ) |
|
74 | 78 | end |
|
75 | 79 | |
|
76 | 80 | def test_groups |
|
77 | 81 | assert_routing( |
|
78 | 82 | { :method => 'post', :path => "/groups/567/users" }, |
|
79 | 83 | { :controller => 'groups', :action => 'add_users', :id => '567' } |
|
80 | 84 | ) |
|
81 | 85 | assert_routing( |
|
82 | 86 | { :method => 'post', :path => "/groups/567/users.xml" }, |
|
83 | 87 | { :controller => 'groups', :action => 'add_users', :id => '567', :format => 'xml' } |
|
84 | 88 | ) |
|
85 | 89 | assert_routing( |
|
86 | 90 | { :method => 'delete', :path => "/groups/567/users/12" }, |
|
87 | 91 | { :controller => 'groups', :action => 'remove_user', :id => '567', :user_id => '12' } |
|
88 | 92 | ) |
|
89 | 93 | assert_routing( |
|
90 | 94 | { :method => 'delete', :path => "/groups/567/users/12.xml" }, |
|
91 | 95 | { :controller => 'groups', :action => 'remove_user', :id => '567', :user_id => '12', :format => 'xml' } |
|
92 | 96 | ) |
|
93 | 97 | assert_routing( |
|
94 | 98 | { :method => 'post', :path => "/groups/destroy_membership/567" }, |
|
95 | 99 | { :controller => 'groups', :action => 'destroy_membership', :id => '567' } |
|
96 | 100 | ) |
|
97 | 101 | assert_routing( |
|
98 | 102 | { :method => 'post', :path => "/groups/edit_membership/567" }, |
|
99 | 103 | { :controller => 'groups', :action => 'edit_membership', :id => '567' } |
|
100 | 104 | ) |
|
101 | 105 | end |
|
102 | 106 | end |
@@ -1,59 +1,63 | |||
|
1 | 1 | # Redmine - project management software |
|
2 | 2 | # Copyright (C) 2006-2013 Jean-Philippe Lang |
|
3 | 3 | # |
|
4 | 4 | # This program is free software; you can redistribute it and/or |
|
5 | 5 | # modify it under the terms of the GNU General Public License |
|
6 | 6 | # as published by the Free Software Foundation; either version 2 |
|
7 | 7 | # of the License, or (at your option) any later version. |
|
8 | 8 | # |
|
9 | 9 | # This program is distributed in the hope that it will be useful, |
|
10 | 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 | 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 | 12 | # GNU General Public License for more details. |
|
13 | 13 | # |
|
14 | 14 | # You should have received a copy of the GNU General Public License |
|
15 | 15 | # along with this program; if not, write to the Free Software |
|
16 | 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
17 | 17 | |
|
18 | 18 | require File.expand_path('../../../test_helper', __FILE__) |
|
19 | 19 | |
|
20 | 20 | class RoutingMembersTest < ActionController::IntegrationTest |
|
21 | 21 | def test_members |
|
22 | 22 | assert_routing( |
|
23 | 23 | { :method => 'get', :path => "/projects/5234/memberships.xml" }, |
|
24 | 24 | { :controller => 'members', :action => 'index', :project_id => '5234', :format => 'xml' } |
|
25 | 25 | ) |
|
26 | 26 | assert_routing( |
|
27 | 27 | { :method => 'get', :path => "/memberships/5234.xml" }, |
|
28 | 28 | { :controller => 'members', :action => 'show', :id => '5234', :format => 'xml' } |
|
29 | 29 | ) |
|
30 | 30 | assert_routing( |
|
31 | 31 | { :method => 'post', :path => "/projects/5234/memberships" }, |
|
32 | 32 | { :controller => 'members', :action => 'create', :project_id => '5234' } |
|
33 | 33 | ) |
|
34 | 34 | assert_routing( |
|
35 | 35 | { :method => 'post', :path => "/projects/5234/memberships.xml" }, |
|
36 | 36 | { :controller => 'members', :action => 'create', :project_id => '5234', :format => 'xml' } |
|
37 | 37 | ) |
|
38 | 38 | assert_routing( |
|
39 | 39 | { :method => 'put', :path => "/memberships/5234" }, |
|
40 | 40 | { :controller => 'members', :action => 'update', :id => '5234' } |
|
41 | 41 | ) |
|
42 | 42 | assert_routing( |
|
43 | 43 | { :method => 'put', :path => "/memberships/5234.xml" }, |
|
44 | 44 | { :controller => 'members', :action => 'update', :id => '5234', :format => 'xml' } |
|
45 | 45 | ) |
|
46 | 46 | assert_routing( |
|
47 | 47 | { :method => 'delete', :path => "/memberships/5234" }, |
|
48 | 48 | { :controller => 'members', :action => 'destroy', :id => '5234' } |
|
49 | 49 | ) |
|
50 | 50 | assert_routing( |
|
51 | 51 | { :method => 'delete', :path => "/memberships/5234.xml" }, |
|
52 | 52 | { :controller => 'members', :action => 'destroy', :id => '5234', :format => 'xml' } |
|
53 | 53 | ) |
|
54 | 54 | assert_routing( |
|
55 | 55 | { :method => 'get', :path => "/projects/5234/memberships/autocomplete" }, |
|
56 | 56 | { :controller => 'members', :action => 'autocomplete', :project_id => '5234' } |
|
57 | 57 | ) |
|
58 | assert_routing( | |
|
59 | { :method => 'get', :path => "/projects/5234/memberships/autocomplete.js" }, | |
|
60 | { :controller => 'members', :action => 'autocomplete', :project_id => '5234', :format => 'js' } | |
|
61 | ) | |
|
58 | 62 | end |
|
59 | 63 | end |
|
1 | NO CONTENT: file was removed |
|
1 | NO CONTENT: file was removed |
General Comments 0
You need to be logged in to leave comments.
Login now