##// END OF EJS Templates
Adds REST API for TimeEntries (#6823)....
Jean-Philippe Lang -
r4347:f7cf8aa87845
parent child
Show More
@@ -0,0 +1,16
1 api.array :time_entries do
2 @entries.each do |time_entry|
3 api.time_entry do
4 api.id time_entry.id
5 api.project(:id => time_entry.project_id, :name => time_entry.project.name) unless time_entry.project.nil?
6 api.issue(:id => time_entry.issue_id) unless time_entry.issue.nil?
7 api.user(:id => time_entry.user_id, :name => time_entry.user.name) unless time_entry.user.nil?
8 api.activity(:id => time_entry.activity_id, :name => time_entry.activity.name) unless time_entry.activity.nil?
9 api.hours time_entry.hours
10 api.comments time_entry.comments
11 api.spent_on time_entry.spent_on
12 api.created_on time_entry.created_on
13 api.updated_on time_entry.updated_on
14 end
15 end
16 end
@@ -0,0 +1,12
1 api.time_entry do
2 api.id @time_entry.id
3 api.project(:id => @time_entry.project_id, :name => @time_entry.project.name) unless @time_entry.project.nil?
4 api.issue(:id => @time_entry.issue_id) unless @time_entry.issue.nil?
5 api.user(:id => @time_entry.user_id, :name => @time_entry.user.name) unless @time_entry.user.nil?
6 api.activity(:id => @time_entry.activity_id, :name => @time_entry.activity.name) unless @time_entry.activity.nil?
7 api.hours @time_entry.hours
8 api.comments @time_entry.comments
9 api.spent_on @time_entry.spent_on
10 api.created_on @time_entry.created_on
11 api.updated_on @time_entry.updated_on
12 end
@@ -0,0 +1,134
1 # Redmine - project management software
2 # Copyright (C) 2006-2010 Jean-Philippe Lang
3 #
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
18 require "#{File.dirname(__FILE__)}/../../test_helper"
19
20 class ApiTest::TimeEntriesTest < ActionController::IntegrationTest
21 fixtures :all
22
23 def setup
24 Setting.rest_api_enabled = '1'
25 end
26
27 context "GET /time_entries.xml" do
28 should "return time entries" do
29 get '/time_entries.xml', {}, :authorization => credentials('jsmith')
30 assert_response :success
31 assert_equal 'application/xml', @response.content_type
32 assert_tag :tag => 'time_entries',
33 :child => {:tag => 'time_entry', :child => {:tag => 'id', :content => '2'}}
34 end
35 end
36
37 context "GET /time_entries/2.xml" do
38 should "return requested time entry" do
39 get '/time_entries/2.xml', {}, :authorization => credentials('jsmith')
40 assert_response :success
41 assert_equal 'application/xml', @response.content_type
42 assert_tag :tag => 'time_entry',
43 :child => {:tag => 'id', :content => '2'}
44 end
45 end
46
47 context "POST /time_entries.xml" do
48 context "with issue_id" do
49 should "return create time entry" do
50 assert_difference 'TimeEntry.count' do
51 post '/time_entries.xml', {:time_entry => {:issue_id => '1', :spent_on => '2010-12-02', :hours => '3.5', :activity_id => '11'}}, :authorization => credentials('jsmith')
52 end
53 assert_response :created
54 assert_equal 'application/xml', @response.content_type
55
56 entry = TimeEntry.first(:order => 'id DESC')
57 assert_equal 'jsmith', entry.user.login
58 assert_equal Issue.find(1), entry.issue
59 assert_equal Project.find(1), entry.project
60 assert_equal Date.parse('2010-12-02'), entry.spent_on
61 assert_equal 3.5, entry.hours
62 assert_equal TimeEntryActivity.find(11), entry.activity
63 end
64 end
65
66 context "with project_id" do
67 should "return create time entry" do
68 assert_difference 'TimeEntry.count' do
69 post '/time_entries.xml', {:time_entry => {:project_id => '1', :spent_on => '2010-12-02', :hours => '3.5', :activity_id => '11'}}, :authorization => credentials('jsmith')
70 end
71 assert_response :created
72 assert_equal 'application/xml', @response.content_type
73
74 entry = TimeEntry.first(:order => 'id DESC')
75 assert_equal 'jsmith', entry.user.login
76 assert_nil entry.issue
77 assert_equal Project.find(1), entry.project
78 assert_equal Date.parse('2010-12-02'), entry.spent_on
79 assert_equal 3.5, entry.hours
80 assert_equal TimeEntryActivity.find(11), entry.activity
81 end
82 end
83
84 context "with invalid parameters" do
85 should "return errors" do
86 assert_no_difference 'TimeEntry.count' do
87 post '/time_entries.xml', {:time_entry => {:project_id => '1', :spent_on => '2010-12-02', :activity_id => '11'}}, :authorization => credentials('jsmith')
88 end
89 assert_response :unprocessable_entity
90 assert_equal 'application/xml', @response.content_type
91
92 assert_tag 'errors', :child => {:tag => 'error', :content => "Hours can't be blank"}
93 end
94 end
95 end
96
97 context "PUT /time_entries/2.xml" do
98 context "with valid parameters" do
99 should "update time entry" do
100 assert_no_difference 'TimeEntry.count' do
101 put '/time_entries/2.xml', {:time_entry => {:comments => 'API Update'}}, :authorization => credentials('jsmith')
102 end
103 assert_response :ok
104 assert_equal 'API Update', TimeEntry.find(2).comments
105 end
106 end
107
108 context "with invalid parameters" do
109 should "return errors" do
110 assert_no_difference 'TimeEntry.count' do
111 put '/time_entries/2.xml', {:time_entry => {:hours => '', :comments => 'API Update'}}, :authorization => credentials('jsmith')
112 end
113 assert_response :unprocessable_entity
114 assert_equal 'application/xml', @response.content_type
115
116 assert_tag 'errors', :child => {:tag => 'error', :content => "Hours can't be blank"}
117 end
118 end
119 end
120
121 context "DELETE /time_entries/2.xml" do
122 should "destroy time entry" do
123 assert_difference 'TimeEntry.count', -1 do
124 delete '/time_entries/2.xml', {}, :authorization => credentials('jsmith')
125 end
126 assert_response :ok
127 assert_nil TimeEntry.find_by_id(2)
128 end
129 end
130
131 def credentials(user, password=nil)
132 ActionController::HttpAuthentication::Basic.encode_credentials(user, password || user)
133 end
134 end
@@ -1,226 +1,274
1 # redMine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2007 Jean-Philippe Lang
2 # Copyright (C) 2006-2010 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 class TimelogController < ApplicationController
18 class TimelogController < ApplicationController
19 menu_item :issues
19 menu_item :issues
20 before_filter :find_project, :only => [:new, :create]
20 before_filter :find_project, :only => [:new, :create]
21 before_filter :find_time_entry, :only => [:edit, :update, :destroy]
21 before_filter :find_time_entry, :only => [:show, :edit, :update, :destroy]
22 before_filter :authorize, :except => [:index]
22 before_filter :authorize, :except => [:index]
23 before_filter :find_optional_project, :only => [:index]
23 before_filter :find_optional_project, :only => [:index]
24
24 accept_key_auth :index, :show, :create, :update, :destroy
25
25 helper :sort
26 helper :sort
26 include SortHelper
27 include SortHelper
27 helper :issues
28 helper :issues
28 include TimelogHelper
29 include TimelogHelper
29 helper :custom_fields
30 helper :custom_fields
30 include CustomFieldsHelper
31 include CustomFieldsHelper
31
32
32 def index
33 def index
33 sort_init 'spent_on', 'desc'
34 sort_init 'spent_on', 'desc'
34 sort_update 'spent_on' => 'spent_on',
35 sort_update 'spent_on' => 'spent_on',
35 'user' => 'user_id',
36 'user' => 'user_id',
36 'activity' => 'activity_id',
37 'activity' => 'activity_id',
37 'project' => "#{Project.table_name}.name",
38 'project' => "#{Project.table_name}.name",
38 'issue' => 'issue_id',
39 'issue' => 'issue_id',
39 'hours' => 'hours'
40 'hours' => 'hours'
40
41
41 cond = ARCondition.new
42 cond = ARCondition.new
42 if @project.nil?
43 if @project.nil?
43 cond << Project.allowed_to_condition(User.current, :view_time_entries)
44 cond << Project.allowed_to_condition(User.current, :view_time_entries)
44 elsif @issue.nil?
45 elsif @issue.nil?
45 cond << @project.project_condition(Setting.display_subprojects_issues?)
46 cond << @project.project_condition(Setting.display_subprojects_issues?)
46 else
47 else
47 cond << "#{Issue.table_name}.root_id = #{@issue.root_id} AND #{Issue.table_name}.lft >= #{@issue.lft} AND #{Issue.table_name}.rgt <= #{@issue.rgt}"
48 cond << "#{Issue.table_name}.root_id = #{@issue.root_id} AND #{Issue.table_name}.lft >= #{@issue.lft} AND #{Issue.table_name}.rgt <= #{@issue.rgt}"
48 end
49 end
49
50
50 retrieve_date_range
51 retrieve_date_range
51 cond << ['spent_on BETWEEN ? AND ?', @from, @to]
52 cond << ['spent_on BETWEEN ? AND ?', @from, @to]
52
53
53 TimeEntry.visible_by(User.current) do
54 TimeEntry.visible_by(User.current) do
54 respond_to do |format|
55 respond_to do |format|
55 format.html {
56 format.html {
56 # Paginate results
57 # Paginate results
57 @entry_count = TimeEntry.count(:include => [:project, :issue], :conditions => cond.conditions)
58 @entry_count = TimeEntry.count(:include => [:project, :issue], :conditions => cond.conditions)
58 @entry_pages = Paginator.new self, @entry_count, per_page_option, params['page']
59 @entry_pages = Paginator.new self, @entry_count, per_page_option, params['page']
59 @entries = TimeEntry.find(:all,
60 @entries = TimeEntry.find(:all,
60 :include => [:project, :activity, :user, {:issue => :tracker}],
61 :include => [:project, :activity, :user, {:issue => :tracker}],
61 :conditions => cond.conditions,
62 :conditions => cond.conditions,
62 :order => sort_clause,
63 :order => sort_clause,
63 :limit => @entry_pages.items_per_page,
64 :limit => @entry_pages.items_per_page,
64 :offset => @entry_pages.current.offset)
65 :offset => @entry_pages.current.offset)
65 @total_hours = TimeEntry.sum(:hours, :include => [:project, :issue], :conditions => cond.conditions).to_f
66 @total_hours = TimeEntry.sum(:hours, :include => [:project, :issue], :conditions => cond.conditions).to_f
66
67
67 render :layout => !request.xhr?
68 render :layout => !request.xhr?
68 }
69 }
70 format.api {
71 @entry_count = TimeEntry.count(:include => [:project, :issue], :conditions => cond.conditions)
72 @entry_pages = Paginator.new self, @entry_count, per_page_option, params['page']
73 @entries = TimeEntry.find(:all,
74 :include => [:project, :activity, :user, {:issue => :tracker}],
75 :conditions => cond.conditions,
76 :order => sort_clause,
77 :limit => @entry_pages.items_per_page,
78 :offset => @entry_pages.current.offset)
79
80 render :template => 'timelog/index.apit'
81 }
69 format.atom {
82 format.atom {
70 entries = TimeEntry.find(:all,
83 entries = TimeEntry.find(:all,
71 :include => [:project, :activity, :user, {:issue => :tracker}],
84 :include => [:project, :activity, :user, {:issue => :tracker}],
72 :conditions => cond.conditions,
85 :conditions => cond.conditions,
73 :order => "#{TimeEntry.table_name}.created_on DESC",
86 :order => "#{TimeEntry.table_name}.created_on DESC",
74 :limit => Setting.feeds_limit.to_i)
87 :limit => Setting.feeds_limit.to_i)
75 render_feed(entries, :title => l(:label_spent_time))
88 render_feed(entries, :title => l(:label_spent_time))
76 }
89 }
77 format.csv {
90 format.csv {
78 # Export all entries
91 # Export all entries
79 @entries = TimeEntry.find(:all,
92 @entries = TimeEntry.find(:all,
80 :include => [:project, :activity, :user, {:issue => [:tracker, :assigned_to, :priority]}],
93 :include => [:project, :activity, :user, {:issue => [:tracker, :assigned_to, :priority]}],
81 :conditions => cond.conditions,
94 :conditions => cond.conditions,
82 :order => sort_clause)
95 :order => sort_clause)
83 send_data(entries_to_csv(@entries), :type => 'text/csv; header=present', :filename => 'timelog.csv')
96 send_data(entries_to_csv(@entries), :type => 'text/csv; header=present', :filename => 'timelog.csv')
84 }
97 }
85 end
98 end
86 end
99 end
87 end
100 end
101
102 def show
103 respond_to do |format|
104 # TODO: Implement html response
105 format.html { render :nothing => true, :status => 406 }
106 format.api { render :template => 'timelog/show.apit' }
107 end
108 end
88
109
89 def new
110 def new
90 @time_entry ||= TimeEntry.new(:project => @project, :issue => @issue, :user => User.current, :spent_on => User.current.today)
111 @time_entry ||= TimeEntry.new(:project => @project, :issue => @issue, :user => User.current, :spent_on => User.current.today)
91 @time_entry.attributes = params[:time_entry]
112 @time_entry.attributes = params[:time_entry]
92
113
93 call_hook(:controller_timelog_edit_before_save, { :params => params, :time_entry => @time_entry })
114 call_hook(:controller_timelog_edit_before_save, { :params => params, :time_entry => @time_entry })
94 render :action => 'edit'
115 render :action => 'edit'
95 end
116 end
96
117
97 verify :method => :post, :only => :create, :render => {:nothing => true, :status => :method_not_allowed }
118 verify :method => :post, :only => :create, :render => {:nothing => true, :status => :method_not_allowed }
98 def create
119 def create
99 @time_entry ||= TimeEntry.new(:project => @project, :issue => @issue, :user => User.current, :spent_on => User.current.today)
120 @time_entry ||= TimeEntry.new(:project => @project, :issue => @issue, :user => User.current, :spent_on => User.current.today)
100 @time_entry.attributes = params[:time_entry]
121 @time_entry.attributes = params[:time_entry]
101
122
102 call_hook(:controller_timelog_edit_before_save, { :params => params, :time_entry => @time_entry })
123 call_hook(:controller_timelog_edit_before_save, { :params => params, :time_entry => @time_entry })
103
124
104 if @time_entry.save
125 if @time_entry.save
105 flash[:notice] = l(:notice_successful_update)
126 respond_to do |format|
106 redirect_back_or_default :action => 'index', :project_id => @time_entry.project
127 format.html {
128 flash[:notice] = l(:notice_successful_update)
129 redirect_back_or_default :action => 'index', :project_id => @time_entry.project
130 }
131 format.api { render :template => 'timelog/show.apit', :status => :created, :location => time_entry_url(@time_entry) }
132 end
107 else
133 else
108 render :action => 'edit'
134 respond_to do |format|
135 format.html { render :action => 'edit' }
136 format.api { render_validation_errors(@time_entry) }
137 end
109 end
138 end
110 end
139 end
111
140
112 def edit
141 def edit
113 @time_entry.attributes = params[:time_entry]
142 @time_entry.attributes = params[:time_entry]
114
143
115 call_hook(:controller_timelog_edit_before_save, { :params => params, :time_entry => @time_entry })
144 call_hook(:controller_timelog_edit_before_save, { :params => params, :time_entry => @time_entry })
116 end
145 end
117
146
118 verify :method => :put, :only => :update, :render => {:nothing => true, :status => :method_not_allowed }
147 verify :method => :put, :only => :update, :render => {:nothing => true, :status => :method_not_allowed }
119 def update
148 def update
120 @time_entry.attributes = params[:time_entry]
149 @time_entry.attributes = params[:time_entry]
121
150
122 call_hook(:controller_timelog_edit_before_save, { :params => params, :time_entry => @time_entry })
151 call_hook(:controller_timelog_edit_before_save, { :params => params, :time_entry => @time_entry })
123
152
124 if @time_entry.save
153 if @time_entry.save
125 flash[:notice] = l(:notice_successful_update)
154 respond_to do |format|
126 redirect_back_or_default :action => 'index', :project_id => @time_entry.project
155 format.html {
156 flash[:notice] = l(:notice_successful_update)
157 redirect_back_or_default :action => 'index', :project_id => @time_entry.project
158 }
159 format.api { head :ok }
160 end
127 else
161 else
128 render :action => 'edit'
162 respond_to do |format|
163 format.html { render :action => 'edit' }
164 format.api { render_validation_errors(@time_entry) }
165 end
129 end
166 end
130 end
167 end
131
168
132 verify :method => :delete, :only => :destroy, :render => {:nothing => true, :status => :method_not_allowed }
169 verify :method => :delete, :only => :destroy, :render => {:nothing => true, :status => :method_not_allowed }
133 def destroy
170 def destroy
134 if @time_entry.destroy && @time_entry.destroyed?
171 if @time_entry.destroy && @time_entry.destroyed?
135 flash[:notice] = l(:notice_successful_delete)
172 respond_to do |format|
173 format.html {
174 flash[:notice] = l(:notice_successful_delete)
175 redirect_to :back
176 }
177 format.api { head :ok }
178 end
136 else
179 else
137 flash[:error] = l(:notice_unable_delete_time_entry)
180 respond_to do |format|
181 format.html {
182 flash[:notice] = l(:notice_unable_delete_time_entry)
183 redirect_to :back
184 }
185 format.api { render_validation_errors(@time_entry) }
186 end
138 end
187 end
139 redirect_to :back
140 rescue ::ActionController::RedirectBackError
188 rescue ::ActionController::RedirectBackError
141 redirect_to :action => 'index', :project_id => @time_entry.project
189 redirect_to :action => 'index', :project_id => @time_entry.project
142 end
190 end
143
191
144 private
192 private
145 def find_time_entry
193 def find_time_entry
146 @time_entry = TimeEntry.find(params[:id])
194 @time_entry = TimeEntry.find(params[:id])
147 unless @time_entry.editable_by?(User.current)
195 unless @time_entry.editable_by?(User.current)
148 render_403
196 render_403
149 return false
197 return false
150 end
198 end
151 @project = @time_entry.project
199 @project = @time_entry.project
152 rescue ActiveRecord::RecordNotFound
200 rescue ActiveRecord::RecordNotFound
153 render_404
201 render_404
154 end
202 end
155
203
156 def find_project
204 def find_project
157 if params[:issue_id]
205 if issue_id = (params[:issue_id] || params[:time_entry] && params[:time_entry][:issue_id])
158 @issue = Issue.find(params[:issue_id])
206 @issue = Issue.find(issue_id)
159 @project = @issue.project
207 @project = @issue.project
160 elsif params[:project_id]
208 elsif project_id = (params[:project_id] || params[:time_entry] && params[:time_entry][:project_id])
161 @project = Project.find(params[:project_id])
209 @project = Project.find(project_id)
162 else
210 else
163 render_404
211 render_404
164 return false
212 return false
165 end
213 end
166 rescue ActiveRecord::RecordNotFound
214 rescue ActiveRecord::RecordNotFound
167 render_404
215 render_404
168 end
216 end
169
217
170 def find_optional_project
218 def find_optional_project
171 if !params[:issue_id].blank?
219 if !params[:issue_id].blank?
172 @issue = Issue.find(params[:issue_id])
220 @issue = Issue.find(params[:issue_id])
173 @project = @issue.project
221 @project = @issue.project
174 elsif !params[:project_id].blank?
222 elsif !params[:project_id].blank?
175 @project = Project.find(params[:project_id])
223 @project = Project.find(params[:project_id])
176 end
224 end
177 deny_access unless User.current.allowed_to?(:view_time_entries, @project, :global => true)
225 deny_access unless User.current.allowed_to?(:view_time_entries, @project, :global => true)
178 end
226 end
179
227
180 # Retrieves the date range based on predefined ranges or specific from/to param dates
228 # Retrieves the date range based on predefined ranges or specific from/to param dates
181 def retrieve_date_range
229 def retrieve_date_range
182 @free_period = false
230 @free_period = false
183 @from, @to = nil, nil
231 @from, @to = nil, nil
184
232
185 if params[:period_type] == '1' || (params[:period_type].nil? && !params[:period].nil?)
233 if params[:period_type] == '1' || (params[:period_type].nil? && !params[:period].nil?)
186 case params[:period].to_s
234 case params[:period].to_s
187 when 'today'
235 when 'today'
188 @from = @to = Date.today
236 @from = @to = Date.today
189 when 'yesterday'
237 when 'yesterday'
190 @from = @to = Date.today - 1
238 @from = @to = Date.today - 1
191 when 'current_week'
239 when 'current_week'
192 @from = Date.today - (Date.today.cwday - 1)%7
240 @from = Date.today - (Date.today.cwday - 1)%7
193 @to = @from + 6
241 @to = @from + 6
194 when 'last_week'
242 when 'last_week'
195 @from = Date.today - 7 - (Date.today.cwday - 1)%7
243 @from = Date.today - 7 - (Date.today.cwday - 1)%7
196 @to = @from + 6
244 @to = @from + 6
197 when '7_days'
245 when '7_days'
198 @from = Date.today - 7
246 @from = Date.today - 7
199 @to = Date.today
247 @to = Date.today
200 when 'current_month'
248 when 'current_month'
201 @from = Date.civil(Date.today.year, Date.today.month, 1)
249 @from = Date.civil(Date.today.year, Date.today.month, 1)
202 @to = (@from >> 1) - 1
250 @to = (@from >> 1) - 1
203 when 'last_month'
251 when 'last_month'
204 @from = Date.civil(Date.today.year, Date.today.month, 1) << 1
252 @from = Date.civil(Date.today.year, Date.today.month, 1) << 1
205 @to = (@from >> 1) - 1
253 @to = (@from >> 1) - 1
206 when '30_days'
254 when '30_days'
207 @from = Date.today - 30
255 @from = Date.today - 30
208 @to = Date.today
256 @to = Date.today
209 when 'current_year'
257 when 'current_year'
210 @from = Date.civil(Date.today.year, 1, 1)
258 @from = Date.civil(Date.today.year, 1, 1)
211 @to = Date.civil(Date.today.year, 12, 31)
259 @to = Date.civil(Date.today.year, 12, 31)
212 end
260 end
213 elsif params[:period_type] == '2' || (params[:period_type].nil? && (!params[:from].nil? || !params[:to].nil?))
261 elsif params[:period_type] == '2' || (params[:period_type].nil? && (!params[:from].nil? || !params[:to].nil?))
214 begin; @from = params[:from].to_s.to_date unless params[:from].blank?; rescue; end
262 begin; @from = params[:from].to_s.to_date unless params[:from].blank?; rescue; end
215 begin; @to = params[:to].to_s.to_date unless params[:to].blank?; rescue; end
263 begin; @to = params[:to].to_s.to_date unless params[:to].blank?; rescue; end
216 @free_period = true
264 @free_period = true
217 else
265 else
218 # default
266 # default
219 end
267 end
220
268
221 @from, @to = @to, @from if @from && @to && @from > @to
269 @from, @to = @to, @from if @from && @to && @from > @to
222 @from ||= (TimeEntry.earilest_date_for_project(@project) || Date.today)
270 @from ||= (TimeEntry.earilest_date_for_project(@project) || Date.today)
223 @to ||= (TimeEntry.latest_date_for_project(@project) || Date.today)
271 @to ||= (TimeEntry.latest_date_for_project(@project) || Date.today)
224 end
272 end
225
273
226 end
274 end
@@ -1,233 +1,233
1 require 'redmine/access_control'
1 require 'redmine/access_control'
2 require 'redmine/menu_manager'
2 require 'redmine/menu_manager'
3 require 'redmine/activity'
3 require 'redmine/activity'
4 require 'redmine/search'
4 require 'redmine/search'
5 require 'redmine/custom_field_format'
5 require 'redmine/custom_field_format'
6 require 'redmine/mime_type'
6 require 'redmine/mime_type'
7 require 'redmine/core_ext'
7 require 'redmine/core_ext'
8 require 'redmine/themes'
8 require 'redmine/themes'
9 require 'redmine/hook'
9 require 'redmine/hook'
10 require 'redmine/plugin'
10 require 'redmine/plugin'
11 require 'redmine/notifiable'
11 require 'redmine/notifiable'
12 require 'redmine/wiki_formatting'
12 require 'redmine/wiki_formatting'
13 require 'redmine/scm/base'
13 require 'redmine/scm/base'
14
14
15 begin
15 begin
16 require_library_or_gem 'RMagick' unless Object.const_defined?(:Magick)
16 require_library_or_gem 'RMagick' unless Object.const_defined?(:Magick)
17 rescue LoadError
17 rescue LoadError
18 # RMagick is not available
18 # RMagick is not available
19 end
19 end
20
20
21 if RUBY_VERSION < '1.9'
21 if RUBY_VERSION < '1.9'
22 require 'faster_csv'
22 require 'faster_csv'
23 else
23 else
24 require 'csv'
24 require 'csv'
25 FCSV = CSV
25 FCSV = CSV
26 end
26 end
27
27
28 Redmine::Scm::Base.add "Subversion"
28 Redmine::Scm::Base.add "Subversion"
29 Redmine::Scm::Base.add "Darcs"
29 Redmine::Scm::Base.add "Darcs"
30 Redmine::Scm::Base.add "Mercurial"
30 Redmine::Scm::Base.add "Mercurial"
31 Redmine::Scm::Base.add "Cvs"
31 Redmine::Scm::Base.add "Cvs"
32 Redmine::Scm::Base.add "Bazaar"
32 Redmine::Scm::Base.add "Bazaar"
33 Redmine::Scm::Base.add "Git"
33 Redmine::Scm::Base.add "Git"
34 Redmine::Scm::Base.add "Filesystem"
34 Redmine::Scm::Base.add "Filesystem"
35
35
36 Redmine::CustomFieldFormat.map do |fields|
36 Redmine::CustomFieldFormat.map do |fields|
37 fields.register Redmine::CustomFieldFormat.new('string', :label => :label_string, :order => 1)
37 fields.register Redmine::CustomFieldFormat.new('string', :label => :label_string, :order => 1)
38 fields.register Redmine::CustomFieldFormat.new('text', :label => :label_text, :order => 2)
38 fields.register Redmine::CustomFieldFormat.new('text', :label => :label_text, :order => 2)
39 fields.register Redmine::CustomFieldFormat.new('int', :label => :label_integer, :order => 3)
39 fields.register Redmine::CustomFieldFormat.new('int', :label => :label_integer, :order => 3)
40 fields.register Redmine::CustomFieldFormat.new('float', :label => :label_float, :order => 4)
40 fields.register Redmine::CustomFieldFormat.new('float', :label => :label_float, :order => 4)
41 fields.register Redmine::CustomFieldFormat.new('list', :label => :label_list, :order => 5)
41 fields.register Redmine::CustomFieldFormat.new('list', :label => :label_list, :order => 5)
42 fields.register Redmine::CustomFieldFormat.new('date', :label => :label_date, :order => 6)
42 fields.register Redmine::CustomFieldFormat.new('date', :label => :label_date, :order => 6)
43 fields.register Redmine::CustomFieldFormat.new('bool', :label => :label_boolean, :order => 7)
43 fields.register Redmine::CustomFieldFormat.new('bool', :label => :label_boolean, :order => 7)
44 end
44 end
45
45
46 # Permissions
46 # Permissions
47 Redmine::AccessControl.map do |map|
47 Redmine::AccessControl.map do |map|
48 map.permission :view_project, {:projects => [:show], :activities => [:index]}, :public => true
48 map.permission :view_project, {:projects => [:show], :activities => [:index]}, :public => true
49 map.permission :search_project, {:search => :index}, :public => true
49 map.permission :search_project, {:search => :index}, :public => true
50 map.permission :add_project, {:projects => [:new, :create]}, :require => :loggedin
50 map.permission :add_project, {:projects => [:new, :create]}, :require => :loggedin
51 map.permission :edit_project, {:projects => [:settings, :edit, :update]}, :require => :member
51 map.permission :edit_project, {:projects => [:settings, :edit, :update]}, :require => :member
52 map.permission :select_project_modules, {:projects => :modules}, :require => :member
52 map.permission :select_project_modules, {:projects => :modules}, :require => :member
53 map.permission :manage_members, {:projects => :settings, :members => [:new, :edit, :destroy, :autocomplete_for_member]}, :require => :member
53 map.permission :manage_members, {:projects => :settings, :members => [:new, :edit, :destroy, :autocomplete_for_member]}, :require => :member
54 map.permission :manage_versions, {:projects => :settings, :versions => [:new, :create, :edit, :update, :close_completed, :destroy]}, :require => :member
54 map.permission :manage_versions, {:projects => :settings, :versions => [:new, :create, :edit, :update, :close_completed, :destroy]}, :require => :member
55 map.permission :add_subprojects, {:projects => [:new, :create]}, :require => :member
55 map.permission :add_subprojects, {:projects => [:new, :create]}, :require => :member
56
56
57 map.project_module :issue_tracking do |map|
57 map.project_module :issue_tracking do |map|
58 # Issue categories
58 # Issue categories
59 map.permission :manage_categories, {:projects => :settings, :issue_categories => [:new, :edit, :destroy]}, :require => :member
59 map.permission :manage_categories, {:projects => :settings, :issue_categories => [:new, :edit, :destroy]}, :require => :member
60 # Issues
60 # Issues
61 map.permission :view_issues, {:issues => [:index, :show],
61 map.permission :view_issues, {:issues => [:index, :show],
62 :auto_complete => [:issues],
62 :auto_complete => [:issues],
63 :context_menus => [:issues],
63 :context_menus => [:issues],
64 :versions => [:index, :show, :status_by],
64 :versions => [:index, :show, :status_by],
65 :journals => :index,
65 :journals => :index,
66 :queries => :index,
66 :queries => :index,
67 :reports => [:issue_report, :issue_report_details]}
67 :reports => [:issue_report, :issue_report_details]}
68 map.permission :add_issues, {:issues => [:new, :create, :update_form]}
68 map.permission :add_issues, {:issues => [:new, :create, :update_form]}
69 map.permission :edit_issues, {:issues => [:edit, :update, :bulk_edit, :bulk_update, :update_form], :journals => [:new]}
69 map.permission :edit_issues, {:issues => [:edit, :update, :bulk_edit, :bulk_update, :update_form], :journals => [:new]}
70 map.permission :manage_issue_relations, {:issue_relations => [:new, :destroy]}
70 map.permission :manage_issue_relations, {:issue_relations => [:new, :destroy]}
71 map.permission :manage_subtasks, {}
71 map.permission :manage_subtasks, {}
72 map.permission :add_issue_notes, {:issues => [:edit, :update], :journals => [:new]}
72 map.permission :add_issue_notes, {:issues => [:edit, :update], :journals => [:new]}
73 map.permission :edit_issue_notes, {:journals => :edit}, :require => :loggedin
73 map.permission :edit_issue_notes, {:journals => :edit}, :require => :loggedin
74 map.permission :edit_own_issue_notes, {:journals => :edit}, :require => :loggedin
74 map.permission :edit_own_issue_notes, {:journals => :edit}, :require => :loggedin
75 map.permission :move_issues, {:issue_moves => [:new, :create]}, :require => :loggedin
75 map.permission :move_issues, {:issue_moves => [:new, :create]}, :require => :loggedin
76 map.permission :delete_issues, {:issues => :destroy}, :require => :member
76 map.permission :delete_issues, {:issues => :destroy}, :require => :member
77 # Queries
77 # Queries
78 map.permission :manage_public_queries, {:queries => [:new, :edit, :destroy]}, :require => :member
78 map.permission :manage_public_queries, {:queries => [:new, :edit, :destroy]}, :require => :member
79 map.permission :save_queries, {:queries => [:new, :edit, :destroy]}, :require => :loggedin
79 map.permission :save_queries, {:queries => [:new, :edit, :destroy]}, :require => :loggedin
80 # Watchers
80 # Watchers
81 map.permission :view_issue_watchers, {}
81 map.permission :view_issue_watchers, {}
82 map.permission :add_issue_watchers, {:watchers => :new}
82 map.permission :add_issue_watchers, {:watchers => :new}
83 map.permission :delete_issue_watchers, {:watchers => :destroy}
83 map.permission :delete_issue_watchers, {:watchers => :destroy}
84 end
84 end
85
85
86 map.project_module :time_tracking do |map|
86 map.project_module :time_tracking do |map|
87 map.permission :log_time, {:timelog => [:new, :create, :edit, :update]}, :require => :loggedin
87 map.permission :log_time, {:timelog => [:new, :create, :edit, :update]}, :require => :loggedin
88 map.permission :view_time_entries, :timelog => [:index], :time_entry_reports => [:report]
88 map.permission :view_time_entries, :timelog => [:index, :show], :time_entry_reports => [:report]
89 map.permission :edit_time_entries, {:timelog => [:new, :create, :edit, :update, :destroy]}, :require => :member
89 map.permission :edit_time_entries, {:timelog => [:new, :create, :edit, :update, :destroy]}, :require => :member
90 map.permission :edit_own_time_entries, {:timelog => [:new, :create, :edit, :update, :destroy]}, :require => :loggedin
90 map.permission :edit_own_time_entries, {:timelog => [:new, :create, :edit, :update, :destroy]}, :require => :loggedin
91 map.permission :manage_project_activities, {:project_enumerations => [:update, :destroy]}, :require => :member
91 map.permission :manage_project_activities, {:project_enumerations => [:update, :destroy]}, :require => :member
92 end
92 end
93
93
94 map.project_module :news do |map|
94 map.project_module :news do |map|
95 map.permission :manage_news, {:news => [:new, :create, :edit, :update, :destroy], :comments => [:destroy]}, :require => :member
95 map.permission :manage_news, {:news => [:new, :create, :edit, :update, :destroy], :comments => [:destroy]}, :require => :member
96 map.permission :view_news, {:news => [:index, :show]}, :public => true
96 map.permission :view_news, {:news => [:index, :show]}, :public => true
97 map.permission :comment_news, {:comments => :create}
97 map.permission :comment_news, {:comments => :create}
98 end
98 end
99
99
100 map.project_module :documents do |map|
100 map.project_module :documents do |map|
101 map.permission :manage_documents, {:documents => [:new, :edit, :destroy, :add_attachment]}, :require => :loggedin
101 map.permission :manage_documents, {:documents => [:new, :edit, :destroy, :add_attachment]}, :require => :loggedin
102 map.permission :view_documents, :documents => [:index, :show, :download]
102 map.permission :view_documents, :documents => [:index, :show, :download]
103 end
103 end
104
104
105 map.project_module :files do |map|
105 map.project_module :files do |map|
106 map.permission :manage_files, {:files => [:new, :create]}, :require => :loggedin
106 map.permission :manage_files, {:files => [:new, :create]}, :require => :loggedin
107 map.permission :view_files, :files => :index, :versions => :download
107 map.permission :view_files, :files => :index, :versions => :download
108 end
108 end
109
109
110 map.project_module :wiki do |map|
110 map.project_module :wiki do |map|
111 map.permission :manage_wiki, {:wikis => [:edit, :destroy]}, :require => :member
111 map.permission :manage_wiki, {:wikis => [:edit, :destroy]}, :require => :member
112 map.permission :rename_wiki_pages, {:wiki => :rename}, :require => :member
112 map.permission :rename_wiki_pages, {:wiki => :rename}, :require => :member
113 map.permission :delete_wiki_pages, {:wiki => :destroy}, :require => :member
113 map.permission :delete_wiki_pages, {:wiki => :destroy}, :require => :member
114 map.permission :view_wiki_pages, :wiki => [:index, :show, :special, :date_index]
114 map.permission :view_wiki_pages, :wiki => [:index, :show, :special, :date_index]
115 map.permission :export_wiki_pages, :wiki => [:export]
115 map.permission :export_wiki_pages, :wiki => [:export]
116 map.permission :view_wiki_edits, :wiki => [:history, :diff, :annotate]
116 map.permission :view_wiki_edits, :wiki => [:history, :diff, :annotate]
117 map.permission :edit_wiki_pages, :wiki => [:edit, :update, :preview, :add_attachment]
117 map.permission :edit_wiki_pages, :wiki => [:edit, :update, :preview, :add_attachment]
118 map.permission :delete_wiki_pages_attachments, {}
118 map.permission :delete_wiki_pages_attachments, {}
119 map.permission :protect_wiki_pages, {:wiki => :protect}, :require => :member
119 map.permission :protect_wiki_pages, {:wiki => :protect}, :require => :member
120 end
120 end
121
121
122 map.project_module :repository do |map|
122 map.project_module :repository do |map|
123 map.permission :manage_repository, {:repositories => [:edit, :committers, :destroy]}, :require => :member
123 map.permission :manage_repository, {:repositories => [:edit, :committers, :destroy]}, :require => :member
124 map.permission :browse_repository, :repositories => [:show, :browse, :entry, :annotate, :changes, :diff, :stats, :graph]
124 map.permission :browse_repository, :repositories => [:show, :browse, :entry, :annotate, :changes, :diff, :stats, :graph]
125 map.permission :view_changesets, :repositories => [:show, :revisions, :revision]
125 map.permission :view_changesets, :repositories => [:show, :revisions, :revision]
126 map.permission :commit_access, {}
126 map.permission :commit_access, {}
127 end
127 end
128
128
129 map.project_module :boards do |map|
129 map.project_module :boards do |map|
130 map.permission :manage_boards, {:boards => [:new, :edit, :destroy]}, :require => :member
130 map.permission :manage_boards, {:boards => [:new, :edit, :destroy]}, :require => :member
131 map.permission :view_messages, {:boards => [:index, :show], :messages => [:show]}, :public => true
131 map.permission :view_messages, {:boards => [:index, :show], :messages => [:show]}, :public => true
132 map.permission :add_messages, {:messages => [:new, :reply, :quote]}
132 map.permission :add_messages, {:messages => [:new, :reply, :quote]}
133 map.permission :edit_messages, {:messages => :edit}, :require => :member
133 map.permission :edit_messages, {:messages => :edit}, :require => :member
134 map.permission :edit_own_messages, {:messages => :edit}, :require => :loggedin
134 map.permission :edit_own_messages, {:messages => :edit}, :require => :loggedin
135 map.permission :delete_messages, {:messages => :destroy}, :require => :member
135 map.permission :delete_messages, {:messages => :destroy}, :require => :member
136 map.permission :delete_own_messages, {:messages => :destroy}, :require => :loggedin
136 map.permission :delete_own_messages, {:messages => :destroy}, :require => :loggedin
137 end
137 end
138
138
139 map.project_module :calendar do |map|
139 map.project_module :calendar do |map|
140 map.permission :view_calendar, :calendars => [:show, :update]
140 map.permission :view_calendar, :calendars => [:show, :update]
141 end
141 end
142
142
143 map.project_module :gantt do |map|
143 map.project_module :gantt do |map|
144 map.permission :view_gantt, :gantts => [:show, :update]
144 map.permission :view_gantt, :gantts => [:show, :update]
145 end
145 end
146 end
146 end
147
147
148 Redmine::MenuManager.map :top_menu do |menu|
148 Redmine::MenuManager.map :top_menu do |menu|
149 menu.push :home, :home_path
149 menu.push :home, :home_path
150 menu.push :my_page, { :controller => 'my', :action => 'page' }, :if => Proc.new { User.current.logged? }
150 menu.push :my_page, { :controller => 'my', :action => 'page' }, :if => Proc.new { User.current.logged? }
151 menu.push :projects, { :controller => 'projects', :action => 'index' }, :caption => :label_project_plural
151 menu.push :projects, { :controller => 'projects', :action => 'index' }, :caption => :label_project_plural
152 menu.push :administration, { :controller => 'admin', :action => 'index' }, :if => Proc.new { User.current.admin? }, :last => true
152 menu.push :administration, { :controller => 'admin', :action => 'index' }, :if => Proc.new { User.current.admin? }, :last => true
153 menu.push :help, Redmine::Info.help_url, :last => true
153 menu.push :help, Redmine::Info.help_url, :last => true
154 end
154 end
155
155
156 Redmine::MenuManager.map :account_menu do |menu|
156 Redmine::MenuManager.map :account_menu do |menu|
157 menu.push :login, :signin_path, :if => Proc.new { !User.current.logged? }
157 menu.push :login, :signin_path, :if => Proc.new { !User.current.logged? }
158 menu.push :register, { :controller => 'account', :action => 'register' }, :if => Proc.new { !User.current.logged? && Setting.self_registration? }
158 menu.push :register, { :controller => 'account', :action => 'register' }, :if => Proc.new { !User.current.logged? && Setting.self_registration? }
159 menu.push :my_account, { :controller => 'my', :action => 'account' }, :if => Proc.new { User.current.logged? }
159 menu.push :my_account, { :controller => 'my', :action => 'account' }, :if => Proc.new { User.current.logged? }
160 menu.push :logout, :signout_path, :if => Proc.new { User.current.logged? }
160 menu.push :logout, :signout_path, :if => Proc.new { User.current.logged? }
161 end
161 end
162
162
163 Redmine::MenuManager.map :application_menu do |menu|
163 Redmine::MenuManager.map :application_menu do |menu|
164 # Empty
164 # Empty
165 end
165 end
166
166
167 Redmine::MenuManager.map :admin_menu do |menu|
167 Redmine::MenuManager.map :admin_menu do |menu|
168 menu.push :projects, {:controller => 'admin', :action => 'projects'}, :caption => :label_project_plural
168 menu.push :projects, {:controller => 'admin', :action => 'projects'}, :caption => :label_project_plural
169 menu.push :users, {:controller => 'users'}, :caption => :label_user_plural
169 menu.push :users, {:controller => 'users'}, :caption => :label_user_plural
170 menu.push :groups, {:controller => 'groups'}, :caption => :label_group_plural
170 menu.push :groups, {:controller => 'groups'}, :caption => :label_group_plural
171 menu.push :roles, {:controller => 'roles'}, :caption => :label_role_and_permissions
171 menu.push :roles, {:controller => 'roles'}, :caption => :label_role_and_permissions
172 menu.push :trackers, {:controller => 'trackers'}, :caption => :label_tracker_plural
172 menu.push :trackers, {:controller => 'trackers'}, :caption => :label_tracker_plural
173 menu.push :issue_statuses, {:controller => 'issue_statuses'}, :caption => :label_issue_status_plural,
173 menu.push :issue_statuses, {:controller => 'issue_statuses'}, :caption => :label_issue_status_plural,
174 :html => {:class => 'issue_statuses'}
174 :html => {:class => 'issue_statuses'}
175 menu.push :workflows, {:controller => 'workflows', :action => 'edit'}, :caption => :label_workflow
175 menu.push :workflows, {:controller => 'workflows', :action => 'edit'}, :caption => :label_workflow
176 menu.push :custom_fields, {:controller => 'custom_fields'}, :caption => :label_custom_field_plural,
176 menu.push :custom_fields, {:controller => 'custom_fields'}, :caption => :label_custom_field_plural,
177 :html => {:class => 'custom_fields'}
177 :html => {:class => 'custom_fields'}
178 menu.push :enumerations, {:controller => 'enumerations'}
178 menu.push :enumerations, {:controller => 'enumerations'}
179 menu.push :settings, {:controller => 'settings'}
179 menu.push :settings, {:controller => 'settings'}
180 menu.push :ldap_authentication, {:controller => 'ldap_auth_sources', :action => 'index'},
180 menu.push :ldap_authentication, {:controller => 'ldap_auth_sources', :action => 'index'},
181 :html => {:class => 'server_authentication'}
181 :html => {:class => 'server_authentication'}
182 menu.push :plugins, {:controller => 'admin', :action => 'plugins'}, :last => true
182 menu.push :plugins, {:controller => 'admin', :action => 'plugins'}, :last => true
183 menu.push :info, {:controller => 'admin', :action => 'info'}, :caption => :label_information_plural, :last => true
183 menu.push :info, {:controller => 'admin', :action => 'info'}, :caption => :label_information_plural, :last => true
184 end
184 end
185
185
186 Redmine::MenuManager.map :project_menu do |menu|
186 Redmine::MenuManager.map :project_menu do |menu|
187 menu.push :overview, { :controller => 'projects', :action => 'show' }
187 menu.push :overview, { :controller => 'projects', :action => 'show' }
188 menu.push :activity, { :controller => 'activities', :action => 'index' }
188 menu.push :activity, { :controller => 'activities', :action => 'index' }
189 menu.push :roadmap, { :controller => 'versions', :action => 'index' }, :param => :project_id,
189 menu.push :roadmap, { :controller => 'versions', :action => 'index' }, :param => :project_id,
190 :if => Proc.new { |p| p.shared_versions.any? }
190 :if => Proc.new { |p| p.shared_versions.any? }
191 menu.push :issues, { :controller => 'issues', :action => 'index' }, :param => :project_id, :caption => :label_issue_plural
191 menu.push :issues, { :controller => 'issues', :action => 'index' }, :param => :project_id, :caption => :label_issue_plural
192 menu.push :new_issue, { :controller => 'issues', :action => 'new' }, :param => :project_id, :caption => :label_issue_new,
192 menu.push :new_issue, { :controller => 'issues', :action => 'new' }, :param => :project_id, :caption => :label_issue_new,
193 :html => { :accesskey => Redmine::AccessKeys.key_for(:new_issue) }
193 :html => { :accesskey => Redmine::AccessKeys.key_for(:new_issue) }
194 menu.push :gantt, { :controller => 'gantts', :action => 'show' }, :param => :project_id, :caption => :label_gantt
194 menu.push :gantt, { :controller => 'gantts', :action => 'show' }, :param => :project_id, :caption => :label_gantt
195 menu.push :calendar, { :controller => 'calendars', :action => 'show' }, :param => :project_id, :caption => :label_calendar
195 menu.push :calendar, { :controller => 'calendars', :action => 'show' }, :param => :project_id, :caption => :label_calendar
196 menu.push :news, { :controller => 'news', :action => 'index' }, :param => :project_id, :caption => :label_news_plural
196 menu.push :news, { :controller => 'news', :action => 'index' }, :param => :project_id, :caption => :label_news_plural
197 menu.push :documents, { :controller => 'documents', :action => 'index' }, :param => :project_id, :caption => :label_document_plural
197 menu.push :documents, { :controller => 'documents', :action => 'index' }, :param => :project_id, :caption => :label_document_plural
198 menu.push :wiki, { :controller => 'wiki', :action => 'show', :id => nil }, :param => :project_id,
198 menu.push :wiki, { :controller => 'wiki', :action => 'show', :id => nil }, :param => :project_id,
199 :if => Proc.new { |p| p.wiki && !p.wiki.new_record? }
199 :if => Proc.new { |p| p.wiki && !p.wiki.new_record? }
200 menu.push :boards, { :controller => 'boards', :action => 'index', :id => nil }, :param => :project_id,
200 menu.push :boards, { :controller => 'boards', :action => 'index', :id => nil }, :param => :project_id,
201 :if => Proc.new { |p| p.boards.any? }, :caption => :label_board_plural
201 :if => Proc.new { |p| p.boards.any? }, :caption => :label_board_plural
202 menu.push :files, { :controller => 'files', :action => 'index' }, :caption => :label_file_plural, :param => :project_id
202 menu.push :files, { :controller => 'files', :action => 'index' }, :caption => :label_file_plural, :param => :project_id
203 menu.push :repository, { :controller => 'repositories', :action => 'show' },
203 menu.push :repository, { :controller => 'repositories', :action => 'show' },
204 :if => Proc.new { |p| p.repository && !p.repository.new_record? }
204 :if => Proc.new { |p| p.repository && !p.repository.new_record? }
205 menu.push :settings, { :controller => 'projects', :action => 'settings' }, :last => true
205 menu.push :settings, { :controller => 'projects', :action => 'settings' }, :last => true
206 end
206 end
207
207
208 Redmine::Activity.map do |activity|
208 Redmine::Activity.map do |activity|
209 activity.register :issues, :class_name => %w(Issue Journal)
209 activity.register :issues, :class_name => %w(Issue Journal)
210 activity.register :changesets
210 activity.register :changesets
211 activity.register :news
211 activity.register :news
212 activity.register :documents, :class_name => %w(Document Attachment)
212 activity.register :documents, :class_name => %w(Document Attachment)
213 activity.register :files, :class_name => 'Attachment'
213 activity.register :files, :class_name => 'Attachment'
214 activity.register :wiki_edits, :class_name => 'WikiContent::Version', :default => false
214 activity.register :wiki_edits, :class_name => 'WikiContent::Version', :default => false
215 activity.register :messages, :default => false
215 activity.register :messages, :default => false
216 activity.register :time_entries, :default => false
216 activity.register :time_entries, :default => false
217 end
217 end
218
218
219 Redmine::Search.map do |search|
219 Redmine::Search.map do |search|
220 search.register :issues
220 search.register :issues
221 search.register :news
221 search.register :news
222 search.register :documents
222 search.register :documents
223 search.register :changesets
223 search.register :changesets
224 search.register :wiki_pages
224 search.register :wiki_pages
225 search.register :messages
225 search.register :messages
226 search.register :projects
226 search.register :projects
227 end
227 end
228
228
229 Redmine::WikiFormatting.map do |format|
229 Redmine::WikiFormatting.map do |format|
230 format.register :textile, Redmine::WikiFormatting::Textile::Formatter, Redmine::WikiFormatting::Textile::Helper
230 format.register :textile, Redmine::WikiFormatting::Textile::Formatter, Redmine::WikiFormatting::Textile::Helper
231 end
231 end
232
232
233 ActionView::Template.register_template_handler :apit, Redmine::Views::ApiTemplateHandler
233 ActionView::Template.register_template_handler :apit, Redmine::Views::ApiTemplateHandler
General Comments 0
You need to be logged in to leave comments. Login now