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