##// END OF EJS Templates
Added feeds auto discovery links on projects/show (patch by Nicolas Chuche)....
Jean-Philippe Lang -
r641:1f991c6a792a
parent child
Show More
@@ -1,98 +1,98
1 # redMine - project management software
1 # redMine - project management software
2 # Copyright (C) 2006-2007 Jean-Philippe Lang
2 # Copyright (C) 2006-2007 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 FeedsController < ApplicationController
18 class FeedsController < ApplicationController
19 before_filter :find_scope
19 before_filter :find_scope
20 session :off
20 session :off
21
21
22 helper :issues
22 helper :issues
23 include IssuesHelper
23 include IssuesHelper
24 helper :custom_fields
24 helper :custom_fields
25 include CustomFieldsHelper
25 include CustomFieldsHelper
26
26
27 # news feeds
27 # news feeds
28 def news
28 def news
29 News.with_scope(:find => @find_options) do
29 News.with_scope(:find => @find_options) do
30 @news = News.find :all, :order => "#{News.table_name}.created_on DESC", :include => [ :author, :project ]
30 @news = News.find :all, :order => "#{News.table_name}.created_on DESC", :include => [ :author, :project ]
31 end
31 end
32 headers["Content-Type"] = "application/rss+xml"
32 headers["Content-Type"] = "application/rss+xml"
33 render :action => 'news_atom' if 'atom' == params[:format]
33 render :action => 'news_atom' if 'atom' == params[:format]
34 end
34 end
35
35
36 # issue feeds
36 # issue feeds
37 def issues
37 def issues
38 if @project && params[:query_id]
38 if @project && params[:query_id]
39 query = Query.find(params[:query_id])
39 query = Query.find(params[:query_id])
40 query.executed_by = @user
40 query.executed_by = @user
41 # ignore query if it's not valid
41 # ignore query if it's not valid
42 query = nil unless query.valid?
42 query = nil unless query.valid?
43 # override with query conditions
43 # override with query conditions
44 @find_options[:conditions] = query.statement if query.valid? and @project == query.project
44 @find_options[:conditions] = query.statement if query.valid? and @project == query.project
45 end
45 end
46
46
47 Issue.with_scope(:find => @find_options) do
47 Issue.with_scope(:find => @find_options) do
48 @issues = Issue.find :all, :include => [:project, :author, :tracker, :status, :custom_values],
48 @issues = Issue.find :all, :include => [:project, :author, :tracker, :status, :custom_values],
49 :order => "#{Issue.table_name}.created_on DESC"
49 :order => "#{Issue.table_name}.created_on DESC"
50 end
50 end
51 @title = (@project ? @project.name : Setting.app_title) + ": " + (query ? query.name : l(:label_reported_issues))
51 @title = (@project ? @project.name : Setting.app_title) + ": " + (query ? query.name : l(:label_reported_issues))
52 headers["Content-Type"] = "application/rss+xml"
52 headers["Content-Type"] = "application/rss+xml"
53 render :action => 'issues_atom' if 'atom' == params[:format]
53 render :action => 'issues_atom' if 'atom' == params[:format]
54 end
54 end
55
55
56 # issue changes feeds
56 # issue changes feeds
57 def history
57 def history
58 if @project && params[:query_id]
58 if @project && params[:query_id]
59 query = Query.find(params[:query_id])
59 query = Query.find(params[:query_id])
60 query.executed_by = @user
60 query.executed_by = @user
61 # ignore query if it's not valid
61 # ignore query if it's not valid
62 query = nil unless query.valid?
62 query = nil unless query.valid?
63 # override with query conditions
63 # override with query conditions
64 @find_options[:conditions] = query.statement if query.valid? and @project == query.project
64 @find_options[:conditions] = query.statement if query.valid? and @project == query.project
65 end
65 end
66
66
67 Journal.with_scope(:find => @find_options) do
67 Journal.with_scope(:find => @find_options) do
68 @journals = Journal.find :all, :include => [ :details, :user, {:issue => [:project, :author, :tracker, :status, :custom_values]} ],
68 @journals = Journal.find :all, :include => [ :details, :user, {:issue => [:project, :author, :tracker, :status, :custom_values]} ],
69 :order => "#{Journal.table_name}.created_on DESC"
69 :order => "#{Journal.table_name}.created_on DESC"
70 end
70 end
71
71
72 @title = (@project ? @project.name : Setting.app_title) + ": " + (query ? query.name : l(:label_reported_issues))
72 @title = (@project ? @project.name : Setting.app_title) + ": " + (query ? query.name : l(:label_changes_details))
73 headers["Content-Type"] = "application/rss+xml"
73 headers["Content-Type"] = "application/rss+xml"
74 render :action => 'history_atom' if 'atom' == params[:format]
74 render :action => 'history_atom' if 'atom' == params[:format]
75 end
75 end
76
76
77 private
77 private
78 # override for feeds specific authentication
78 # override for feeds specific authentication
79 def check_if_login_required
79 def check_if_login_required
80 @user = User.find_by_rss_key(params[:key])
80 @user = User.find_by_rss_key(params[:key])
81 render(:nothing => true, :status => 403) and return false if !@user && Setting.login_required?
81 render(:nothing => true, :status => 403) and return false if !@user && Setting.login_required?
82 end
82 end
83
83
84 def find_scope
84 def find_scope
85 if params[:project_id]
85 if params[:project_id]
86 # project feed
86 # project feed
87 # check if project is public or if the user is a member
87 # check if project is public or if the user is a member
88 @project = Project.find(params[:project_id])
88 @project = Project.find(params[:project_id])
89 render(:nothing => true, :status => 403) and return false unless @project.is_public? || (@user && @user.role_for_project(@project))
89 render(:nothing => true, :status => 403) and return false unless @project.is_public? || (@user && @user.role_for_project(@project))
90 scope = ["#{Project.table_name}.id=?", params[:project_id].to_i]
90 scope = ["#{Project.table_name}.id=?", params[:project_id].to_i]
91 else
91 else
92 # global feed
92 # global feed
93 scope = ["#{Project.table_name}.is_public=?", true]
93 scope = ["#{Project.table_name}.is_public=?", true]
94 end
94 end
95 @find_options = {:conditions => scope, :limit => Setting.feeds_limit.to_i}
95 @find_options = {:conditions => scope, :limit => Setting.feeds_limit.to_i}
96 return true
96 return true
97 end
97 end
98 end
98 end
@@ -1,672 +1,674
1 # redMine - project management software
1 # redMine - project management software
2 # Copyright (C) 2006-2007 Jean-Philippe Lang
2 # Copyright (C) 2006-2007 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 require 'csv'
18 require 'csv'
19
19
20 class ProjectsController < ApplicationController
20 class ProjectsController < ApplicationController
21 layout 'base'
21 layout 'base'
22 before_filter :find_project, :except => [ :index, :list, :add ]
22 before_filter :find_project, :except => [ :index, :list, :add ]
23 before_filter :authorize, :except => [ :index, :list, :add, :archive, :unarchive, :destroy ]
23 before_filter :authorize, :except => [ :index, :list, :add, :archive, :unarchive, :destroy ]
24 before_filter :require_admin, :only => [ :add, :archive, :unarchive, :destroy ]
24 before_filter :require_admin, :only => [ :add, :archive, :unarchive, :destroy ]
25
25
26 cache_sweeper :project_sweeper, :only => [ :add, :edit, :archive, :unarchive, :destroy ]
26 cache_sweeper :project_sweeper, :only => [ :add, :edit, :archive, :unarchive, :destroy ]
27 cache_sweeper :issue_sweeper, :only => [ :add_issue ]
27 cache_sweeper :issue_sweeper, :only => [ :add_issue ]
28
28
29 helper :sort
29 helper :sort
30 include SortHelper
30 include SortHelper
31 helper :custom_fields
31 helper :custom_fields
32 include CustomFieldsHelper
32 include CustomFieldsHelper
33 helper :ifpdf
33 helper :ifpdf
34 include IfpdfHelper
34 include IfpdfHelper
35 helper IssuesHelper
35 helper IssuesHelper
36 helper :queries
36 helper :queries
37 include QueriesHelper
37 include QueriesHelper
38 helper :repositories
38 helper :repositories
39 include RepositoriesHelper
39 include RepositoriesHelper
40
40
41 def index
41 def index
42 list
42 list
43 render :action => 'list' unless request.xhr?
43 render :action => 'list' unless request.xhr?
44 end
44 end
45
45
46 # Lists public projects
46 # Lists public projects
47 def list
47 def list
48 sort_init "#{Project.table_name}.name", "asc"
48 sort_init "#{Project.table_name}.name", "asc"
49 sort_update
49 sort_update
50 @project_count = Project.count(:all, :conditions => Project.visible_by(logged_in_user))
50 @project_count = Project.count(:all, :conditions => Project.visible_by(logged_in_user))
51 @project_pages = Paginator.new self, @project_count,
51 @project_pages = Paginator.new self, @project_count,
52 15,
52 15,
53 params['page']
53 params['page']
54 @projects = Project.find :all, :order => sort_clause,
54 @projects = Project.find :all, :order => sort_clause,
55 :conditions => Project.visible_by(logged_in_user),
55 :conditions => Project.visible_by(logged_in_user),
56 :include => :parent,
56 :include => :parent,
57 :limit => @project_pages.items_per_page,
57 :limit => @project_pages.items_per_page,
58 :offset => @project_pages.current.offset
58 :offset => @project_pages.current.offset
59
59
60 render :action => "list", :layout => false if request.xhr?
60 render :action => "list", :layout => false if request.xhr?
61 end
61 end
62
62
63 # Add a new project
63 # Add a new project
64 def add
64 def add
65 @custom_fields = IssueCustomField.find(:all)
65 @custom_fields = IssueCustomField.find(:all)
66 @root_projects = Project.find(:all, :conditions => "parent_id is null")
66 @root_projects = Project.find(:all, :conditions => "parent_id is null")
67 @project = Project.new(params[:project])
67 @project = Project.new(params[:project])
68 if request.get?
68 if request.get?
69 @custom_values = ProjectCustomField.find(:all).collect { |x| CustomValue.new(:custom_field => x, :customized => @project) }
69 @custom_values = ProjectCustomField.find(:all).collect { |x| CustomValue.new(:custom_field => x, :customized => @project) }
70 else
70 else
71 @project.custom_fields = CustomField.find(params[:custom_field_ids]) if params[:custom_field_ids]
71 @project.custom_fields = CustomField.find(params[:custom_field_ids]) if params[:custom_field_ids]
72 @custom_values = ProjectCustomField.find(:all).collect { |x| CustomValue.new(:custom_field => x, :customized => @project, :value => params["custom_fields"][x.id.to_s]) }
72 @custom_values = ProjectCustomField.find(:all).collect { |x| CustomValue.new(:custom_field => x, :customized => @project, :value => params["custom_fields"][x.id.to_s]) }
73 @project.custom_values = @custom_values
73 @project.custom_values = @custom_values
74 if params[:repository_enabled] && params[:repository_enabled] == "1"
74 if params[:repository_enabled] && params[:repository_enabled] == "1"
75 @project.repository = Repository.factory(params[:repository_scm])
75 @project.repository = Repository.factory(params[:repository_scm])
76 @project.repository.attributes = params[:repository]
76 @project.repository.attributes = params[:repository]
77 end
77 end
78 if "1" == params[:wiki_enabled]
78 if "1" == params[:wiki_enabled]
79 @project.wiki = Wiki.new
79 @project.wiki = Wiki.new
80 @project.wiki.attributes = params[:wiki]
80 @project.wiki.attributes = params[:wiki]
81 end
81 end
82 if @project.save
82 if @project.save
83 flash[:notice] = l(:notice_successful_create)
83 flash[:notice] = l(:notice_successful_create)
84 redirect_to :controller => 'admin', :action => 'projects'
84 redirect_to :controller => 'admin', :action => 'projects'
85 end
85 end
86 end
86 end
87 end
87 end
88
88
89 # Show @project
89 # Show @project
90 def show
90 def show
91 @custom_values = @project.custom_values.find(:all, :include => :custom_field)
91 @custom_values = @project.custom_values.find(:all, :include => :custom_field)
92 @members_by_role = @project.members.find(:all, :include => [:user, :role], :order => 'position').group_by {|m| m.role}
92 @members_by_role = @project.members.find(:all, :include => [:user, :role], :order => 'position').group_by {|m| m.role}
93 @subprojects = @project.active_children
93 @subprojects = @project.active_children
94 @news = @project.news.find(:all, :limit => 5, :include => [ :author, :project ], :order => "#{News.table_name}.created_on DESC")
94 @news = @project.news.find(:all, :limit => 5, :include => [ :author, :project ], :order => "#{News.table_name}.created_on DESC")
95 @trackers = Tracker.find(:all, :order => 'position')
95 @trackers = Tracker.find(:all, :order => 'position')
96 @open_issues_by_tracker = Issue.count(:group => :tracker, :joins => "INNER JOIN #{IssueStatus.table_name} ON #{IssueStatus.table_name}.id = #{Issue.table_name}.status_id", :conditions => ["project_id=? and #{IssueStatus.table_name}.is_closed=?", @project.id, false])
96 @open_issues_by_tracker = Issue.count(:group => :tracker, :joins => "INNER JOIN #{IssueStatus.table_name} ON #{IssueStatus.table_name}.id = #{Issue.table_name}.status_id", :conditions => ["project_id=? and #{IssueStatus.table_name}.is_closed=?", @project.id, false])
97 @total_issues_by_tracker = Issue.count(:group => :tracker, :conditions => ["project_id=?", @project.id])
97 @total_issues_by_tracker = Issue.count(:group => :tracker, :conditions => ["project_id=?", @project.id])
98
99 @key = logged_in_user.get_or_create_rss_key.value if logged_in_user
98 end
100 end
99
101
100 def settings
102 def settings
101 @root_projects = Project::find(:all, :conditions => ["parent_id is null and id <> ?", @project.id])
103 @root_projects = Project::find(:all, :conditions => ["parent_id is null and id <> ?", @project.id])
102 @custom_fields = IssueCustomField.find(:all)
104 @custom_fields = IssueCustomField.find(:all)
103 @issue_category ||= IssueCategory.new
105 @issue_category ||= IssueCategory.new
104 @member ||= @project.members.new
106 @member ||= @project.members.new
105 @custom_values ||= ProjectCustomField.find(:all).collect { |x| @project.custom_values.find_by_custom_field_id(x.id) || CustomValue.new(:custom_field => x) }
107 @custom_values ||= ProjectCustomField.find(:all).collect { |x| @project.custom_values.find_by_custom_field_id(x.id) || CustomValue.new(:custom_field => x) }
106 end
108 end
107
109
108 # Edit @project
110 # Edit @project
109 def edit
111 def edit
110 if request.post?
112 if request.post?
111 @project.custom_fields = IssueCustomField.find(params[:custom_field_ids]) if params[:custom_field_ids]
113 @project.custom_fields = IssueCustomField.find(params[:custom_field_ids]) if params[:custom_field_ids]
112 if params[:custom_fields]
114 if params[:custom_fields]
113 @custom_values = ProjectCustomField.find(:all).collect { |x| CustomValue.new(:custom_field => x, :customized => @project, :value => params["custom_fields"][x.id.to_s]) }
115 @custom_values = ProjectCustomField.find(:all).collect { |x| CustomValue.new(:custom_field => x, :customized => @project, :value => params["custom_fields"][x.id.to_s]) }
114 @project.custom_values = @custom_values
116 @project.custom_values = @custom_values
115 end
117 end
116 if params[:repository_enabled]
118 if params[:repository_enabled]
117 case params[:repository_enabled]
119 case params[:repository_enabled]
118 when "0"
120 when "0"
119 @project.repository = nil
121 @project.repository = nil
120 when "1"
122 when "1"
121 @project.repository ||= Repository.factory(params[:repository_scm])
123 @project.repository ||= Repository.factory(params[:repository_scm])
122 @project.repository.update_attributes params[:repository] if @project.repository
124 @project.repository.update_attributes params[:repository] if @project.repository
123 end
125 end
124 end
126 end
125 if params[:wiki_enabled]
127 if params[:wiki_enabled]
126 case params[:wiki_enabled]
128 case params[:wiki_enabled]
127 when "0"
129 when "0"
128 @project.wiki.destroy if @project.wiki
130 @project.wiki.destroy if @project.wiki
129 when "1"
131 when "1"
130 @project.wiki ||= Wiki.new
132 @project.wiki ||= Wiki.new
131 @project.wiki.update_attributes params[:wiki]
133 @project.wiki.update_attributes params[:wiki]
132 end
134 end
133 end
135 end
134 @project.attributes = params[:project]
136 @project.attributes = params[:project]
135 if @project.save
137 if @project.save
136 flash[:notice] = l(:notice_successful_update)
138 flash[:notice] = l(:notice_successful_update)
137 redirect_to :action => 'settings', :id => @project
139 redirect_to :action => 'settings', :id => @project
138 else
140 else
139 settings
141 settings
140 render :action => 'settings'
142 render :action => 'settings'
141 end
143 end
142 end
144 end
143 end
145 end
144
146
145 def archive
147 def archive
146 @project.archive if request.post? && @project.active?
148 @project.archive if request.post? && @project.active?
147 redirect_to :controller => 'admin', :action => 'projects'
149 redirect_to :controller => 'admin', :action => 'projects'
148 end
150 end
149
151
150 def unarchive
152 def unarchive
151 @project.unarchive if request.post? && !@project.active?
153 @project.unarchive if request.post? && !@project.active?
152 redirect_to :controller => 'admin', :action => 'projects'
154 redirect_to :controller => 'admin', :action => 'projects'
153 end
155 end
154
156
155 # Delete @project
157 # Delete @project
156 def destroy
158 def destroy
157 @project_to_destroy = @project
159 @project_to_destroy = @project
158 if request.post? and params[:confirm]
160 if request.post? and params[:confirm]
159 @project_to_destroy.destroy
161 @project_to_destroy.destroy
160 redirect_to :controller => 'admin', :action => 'projects'
162 redirect_to :controller => 'admin', :action => 'projects'
161 end
163 end
162 # hide project in layout
164 # hide project in layout
163 @project = nil
165 @project = nil
164 end
166 end
165
167
166 # Add a new issue category to @project
168 # Add a new issue category to @project
167 def add_issue_category
169 def add_issue_category
168 @category = @project.issue_categories.build(params[:category])
170 @category = @project.issue_categories.build(params[:category])
169 if request.post? and @category.save
171 if request.post? and @category.save
170 flash[:notice] = l(:notice_successful_create)
172 flash[:notice] = l(:notice_successful_create)
171 redirect_to :action => 'settings', :tab => 'categories', :id => @project
173 redirect_to :action => 'settings', :tab => 'categories', :id => @project
172 end
174 end
173 end
175 end
174
176
175 # Add a new version to @project
177 # Add a new version to @project
176 def add_version
178 def add_version
177 @version = @project.versions.build(params[:version])
179 @version = @project.versions.build(params[:version])
178 if request.post? and @version.save
180 if request.post? and @version.save
179 flash[:notice] = l(:notice_successful_create)
181 flash[:notice] = l(:notice_successful_create)
180 redirect_to :action => 'settings', :tab => 'versions', :id => @project
182 redirect_to :action => 'settings', :tab => 'versions', :id => @project
181 end
183 end
182 end
184 end
183
185
184 # Add a new member to @project
186 # Add a new member to @project
185 def add_member
187 def add_member
186 @member = @project.members.build(params[:member])
188 @member = @project.members.build(params[:member])
187 if request.post? && @member.save
189 if request.post? && @member.save
188 respond_to do |format|
190 respond_to do |format|
189 format.html { redirect_to :action => 'settings', :tab => 'members', :id => @project }
191 format.html { redirect_to :action => 'settings', :tab => 'members', :id => @project }
190 format.js { render(:update) {|page| page.replace_html "tab-content-members", :partial => 'members'} }
192 format.js { render(:update) {|page| page.replace_html "tab-content-members", :partial => 'members'} }
191 end
193 end
192 else
194 else
193 settings
195 settings
194 render :action => 'settings'
196 render :action => 'settings'
195 end
197 end
196 end
198 end
197
199
198 # Show members list of @project
200 # Show members list of @project
199 def list_members
201 def list_members
200 @members = @project.members.find(:all)
202 @members = @project.members.find(:all)
201 end
203 end
202
204
203 # Add a new document to @project
205 # Add a new document to @project
204 def add_document
206 def add_document
205 @categories = Enumeration::get_values('DCAT')
207 @categories = Enumeration::get_values('DCAT')
206 @document = @project.documents.build(params[:document])
208 @document = @project.documents.build(params[:document])
207 if request.post? and @document.save
209 if request.post? and @document.save
208 # Save the attachments
210 # Save the attachments
209 params[:attachments].each { |a|
211 params[:attachments].each { |a|
210 Attachment.create(:container => @document, :file => a, :author => logged_in_user) unless a.size == 0
212 Attachment.create(:container => @document, :file => a, :author => logged_in_user) unless a.size == 0
211 } if params[:attachments] and params[:attachments].is_a? Array
213 } if params[:attachments] and params[:attachments].is_a? Array
212 flash[:notice] = l(:notice_successful_create)
214 flash[:notice] = l(:notice_successful_create)
213 Mailer.deliver_document_add(@document) if Permission.find_by_controller_and_action(params[:controller], params[:action]).mail_enabled?
215 Mailer.deliver_document_add(@document) if Permission.find_by_controller_and_action(params[:controller], params[:action]).mail_enabled?
214 redirect_to :action => 'list_documents', :id => @project
216 redirect_to :action => 'list_documents', :id => @project
215 end
217 end
216 end
218 end
217
219
218 # Show documents list of @project
220 # Show documents list of @project
219 def list_documents
221 def list_documents
220 @documents = @project.documents.find :all, :include => :category
222 @documents = @project.documents.find :all, :include => :category
221 end
223 end
222
224
223 # Add a new issue to @project
225 # Add a new issue to @project
224 def add_issue
226 def add_issue
225 @tracker = Tracker.find(params[:tracker_id])
227 @tracker = Tracker.find(params[:tracker_id])
226 @priorities = Enumeration::get_values('IPRI')
228 @priorities = Enumeration::get_values('IPRI')
227
229
228 default_status = IssueStatus.default
230 default_status = IssueStatus.default
229 unless default_status
231 unless default_status
230 flash.now[:error] = 'No default issue status defined. Please check your configuration.'
232 flash.now[:error] = 'No default issue status defined. Please check your configuration.'
231 render :nothing => true, :layout => true
233 render :nothing => true, :layout => true
232 return
234 return
233 end
235 end
234 @issue = Issue.new(:project => @project, :tracker => @tracker)
236 @issue = Issue.new(:project => @project, :tracker => @tracker)
235 @issue.status = default_status
237 @issue.status = default_status
236 @allowed_statuses = ([default_status] + default_status.find_new_statuses_allowed_to(logged_in_user.role_for_project(@project), @issue.tracker))if logged_in_user
238 @allowed_statuses = ([default_status] + default_status.find_new_statuses_allowed_to(logged_in_user.role_for_project(@project), @issue.tracker))if logged_in_user
237 if request.get?
239 if request.get?
238 @issue.start_date = Date.today
240 @issue.start_date = Date.today
239 @custom_values = @project.custom_fields_for_issues(@tracker).collect { |x| CustomValue.new(:custom_field => x, :customized => @issue) }
241 @custom_values = @project.custom_fields_for_issues(@tracker).collect { |x| CustomValue.new(:custom_field => x, :customized => @issue) }
240 else
242 else
241 @issue.attributes = params[:issue]
243 @issue.attributes = params[:issue]
242
244
243 requested_status = IssueStatus.find_by_id(params[:issue][:status_id])
245 requested_status = IssueStatus.find_by_id(params[:issue][:status_id])
244 @issue.status = (@allowed_statuses.include? requested_status) ? requested_status : default_status
246 @issue.status = (@allowed_statuses.include? requested_status) ? requested_status : default_status
245
247
246 @issue.author_id = self.logged_in_user.id if self.logged_in_user
248 @issue.author_id = self.logged_in_user.id if self.logged_in_user
247 # Multiple file upload
249 # Multiple file upload
248 @attachments = []
250 @attachments = []
249 params[:attachments].each { |a|
251 params[:attachments].each { |a|
250 @attachments << Attachment.new(:container => @issue, :file => a, :author => logged_in_user) unless a.size == 0
252 @attachments << Attachment.new(:container => @issue, :file => a, :author => logged_in_user) unless a.size == 0
251 } if params[:attachments] and params[:attachments].is_a? Array
253 } if params[:attachments] and params[:attachments].is_a? Array
252 @custom_values = @project.custom_fields_for_issues(@tracker).collect { |x| CustomValue.new(:custom_field => x, :customized => @issue, :value => params["custom_fields"][x.id.to_s]) }
254 @custom_values = @project.custom_fields_for_issues(@tracker).collect { |x| CustomValue.new(:custom_field => x, :customized => @issue, :value => params["custom_fields"][x.id.to_s]) }
253 @issue.custom_values = @custom_values
255 @issue.custom_values = @custom_values
254 if @issue.save
256 if @issue.save
255 @attachments.each(&:save)
257 @attachments.each(&:save)
256 flash[:notice] = l(:notice_successful_create)
258 flash[:notice] = l(:notice_successful_create)
257 Mailer.deliver_issue_add(@issue) if Permission.find_by_controller_and_action(params[:controller], params[:action]).mail_enabled?
259 Mailer.deliver_issue_add(@issue) if Permission.find_by_controller_and_action(params[:controller], params[:action]).mail_enabled?
258 redirect_to :action => 'list_issues', :id => @project
260 redirect_to :action => 'list_issues', :id => @project
259 end
261 end
260 end
262 end
261 end
263 end
262
264
263 # Show filtered/sorted issues list of @project
265 # Show filtered/sorted issues list of @project
264 def list_issues
266 def list_issues
265 sort_init "#{Issue.table_name}.id", "desc"
267 sort_init "#{Issue.table_name}.id", "desc"
266 sort_update
268 sort_update
267
269
268 retrieve_query
270 retrieve_query
269
271
270 @results_per_page_options = [ 15, 25, 50, 100 ]
272 @results_per_page_options = [ 15, 25, 50, 100 ]
271 if params[:per_page] and @results_per_page_options.include? params[:per_page].to_i
273 if params[:per_page] and @results_per_page_options.include? params[:per_page].to_i
272 @results_per_page = params[:per_page].to_i
274 @results_per_page = params[:per_page].to_i
273 session[:results_per_page] = @results_per_page
275 session[:results_per_page] = @results_per_page
274 else
276 else
275 @results_per_page = session[:results_per_page] || 25
277 @results_per_page = session[:results_per_page] || 25
276 end
278 end
277
279
278 if @query.valid?
280 if @query.valid?
279 @issue_count = Issue.count(:include => [:status, :project, :custom_values], :conditions => @query.statement)
281 @issue_count = Issue.count(:include => [:status, :project, :custom_values], :conditions => @query.statement)
280 @issue_pages = Paginator.new self, @issue_count, @results_per_page, params['page']
282 @issue_pages = Paginator.new self, @issue_count, @results_per_page, params['page']
281 @issues = Issue.find :all, :order => sort_clause,
283 @issues = Issue.find :all, :order => sort_clause,
282 :include => [ :assigned_to, :status, :tracker, :project, :priority, :custom_values ],
284 :include => [ :assigned_to, :status, :tracker, :project, :priority, :custom_values ],
283 :conditions => @query.statement,
285 :conditions => @query.statement,
284 :limit => @issue_pages.items_per_page,
286 :limit => @issue_pages.items_per_page,
285 :offset => @issue_pages.current.offset
287 :offset => @issue_pages.current.offset
286 end
288 end
287 render :layout => false if request.xhr?
289 render :layout => false if request.xhr?
288 end
290 end
289
291
290 # Export filtered/sorted issues list to CSV
292 # Export filtered/sorted issues list to CSV
291 def export_issues_csv
293 def export_issues_csv
292 sort_init "#{Issue.table_name}.id", "desc"
294 sort_init "#{Issue.table_name}.id", "desc"
293 sort_update
295 sort_update
294
296
295 retrieve_query
297 retrieve_query
296 render :action => 'list_issues' and return unless @query.valid?
298 render :action => 'list_issues' and return unless @query.valid?
297
299
298 @issues = Issue.find :all, :order => sort_clause,
300 @issues = Issue.find :all, :order => sort_clause,
299 :include => [ :assigned_to, :author, :status, :tracker, :priority, :project, {:custom_values => :custom_field} ],
301 :include => [ :assigned_to, :author, :status, :tracker, :priority, :project, {:custom_values => :custom_field} ],
300 :conditions => @query.statement,
302 :conditions => @query.statement,
301 :limit => Setting.issues_export_limit.to_i
303 :limit => Setting.issues_export_limit.to_i
302
304
303 ic = Iconv.new(l(:general_csv_encoding), 'UTF-8')
305 ic = Iconv.new(l(:general_csv_encoding), 'UTF-8')
304 export = StringIO.new
306 export = StringIO.new
305 CSV::Writer.generate(export, l(:general_csv_separator)) do |csv|
307 CSV::Writer.generate(export, l(:general_csv_separator)) do |csv|
306 # csv header fields
308 # csv header fields
307 headers = [ "#", l(:field_status),
309 headers = [ "#", l(:field_status),
308 l(:field_project),
310 l(:field_project),
309 l(:field_tracker),
311 l(:field_tracker),
310 l(:field_priority),
312 l(:field_priority),
311 l(:field_subject),
313 l(:field_subject),
312 l(:field_assigned_to),
314 l(:field_assigned_to),
313 l(:field_author),
315 l(:field_author),
314 l(:field_start_date),
316 l(:field_start_date),
315 l(:field_due_date),
317 l(:field_due_date),
316 l(:field_done_ratio),
318 l(:field_done_ratio),
317 l(:field_created_on),
319 l(:field_created_on),
318 l(:field_updated_on)
320 l(:field_updated_on)
319 ]
321 ]
320 for custom_field in @project.all_custom_fields
322 for custom_field in @project.all_custom_fields
321 headers << custom_field.name
323 headers << custom_field.name
322 end
324 end
323 csv << headers.collect {|c| begin; ic.iconv(c.to_s); rescue; c.to_s; end }
325 csv << headers.collect {|c| begin; ic.iconv(c.to_s); rescue; c.to_s; end }
324 # csv lines
326 # csv lines
325 @issues.each do |issue|
327 @issues.each do |issue|
326 fields = [issue.id, issue.status.name,
328 fields = [issue.id, issue.status.name,
327 issue.project.name,
329 issue.project.name,
328 issue.tracker.name,
330 issue.tracker.name,
329 issue.priority.name,
331 issue.priority.name,
330 issue.subject,
332 issue.subject,
331 (issue.assigned_to ? issue.assigned_to.name : ""),
333 (issue.assigned_to ? issue.assigned_to.name : ""),
332 issue.author.name,
334 issue.author.name,
333 issue.start_date ? l_date(issue.start_date) : nil,
335 issue.start_date ? l_date(issue.start_date) : nil,
334 issue.due_date ? l_date(issue.due_date) : nil,
336 issue.due_date ? l_date(issue.due_date) : nil,
335 issue.done_ratio,
337 issue.done_ratio,
336 l_datetime(issue.created_on),
338 l_datetime(issue.created_on),
337 l_datetime(issue.updated_on)
339 l_datetime(issue.updated_on)
338 ]
340 ]
339 for custom_field in @project.all_custom_fields
341 for custom_field in @project.all_custom_fields
340 fields << (show_value issue.custom_value_for(custom_field))
342 fields << (show_value issue.custom_value_for(custom_field))
341 end
343 end
342 csv << fields.collect {|c| begin; ic.iconv(c.to_s); rescue; c.to_s; end }
344 csv << fields.collect {|c| begin; ic.iconv(c.to_s); rescue; c.to_s; end }
343 end
345 end
344 end
346 end
345 export.rewind
347 export.rewind
346 send_data(export.read, :type => 'text/csv; header=present', :filename => 'export.csv')
348 send_data(export.read, :type => 'text/csv; header=present', :filename => 'export.csv')
347 end
349 end
348
350
349 # Export filtered/sorted issues to PDF
351 # Export filtered/sorted issues to PDF
350 def export_issues_pdf
352 def export_issues_pdf
351 sort_init "#{Issue.table_name}.id", "desc"
353 sort_init "#{Issue.table_name}.id", "desc"
352 sort_update
354 sort_update
353
355
354 retrieve_query
356 retrieve_query
355 render :action => 'list_issues' and return unless @query.valid?
357 render :action => 'list_issues' and return unless @query.valid?
356
358
357 @issues = Issue.find :all, :order => sort_clause,
359 @issues = Issue.find :all, :order => sort_clause,
358 :include => [ :author, :status, :tracker, :priority, :project, :custom_values ],
360 :include => [ :author, :status, :tracker, :priority, :project, :custom_values ],
359 :conditions => @query.statement,
361 :conditions => @query.statement,
360 :limit => Setting.issues_export_limit.to_i
362 :limit => Setting.issues_export_limit.to_i
361
363
362 @options_for_rfpdf ||= {}
364 @options_for_rfpdf ||= {}
363 @options_for_rfpdf[:file_name] = "export.pdf"
365 @options_for_rfpdf[:file_name] = "export.pdf"
364 render :layout => false
366 render :layout => false
365 end
367 end
366
368
367 def move_issues
369 def move_issues
368 @issues = @project.issues.find(params[:issue_ids]) if params[:issue_ids]
370 @issues = @project.issues.find(params[:issue_ids]) if params[:issue_ids]
369 redirect_to :action => 'list_issues', :id => @project and return unless @issues
371 redirect_to :action => 'list_issues', :id => @project and return unless @issues
370 @projects = []
372 @projects = []
371 # find projects to which the user is allowed to move the issue
373 # find projects to which the user is allowed to move the issue
372 @logged_in_user.memberships.each {|m| @projects << m.project if Permission.allowed_to_role("projects/move_issues", m.role)}
374 @logged_in_user.memberships.each {|m| @projects << m.project if Permission.allowed_to_role("projects/move_issues", m.role)}
373 # issue can be moved to any tracker
375 # issue can be moved to any tracker
374 @trackers = Tracker.find(:all)
376 @trackers = Tracker.find(:all)
375 if request.post? and params[:new_project_id] and params[:new_tracker_id]
377 if request.post? and params[:new_project_id] and params[:new_tracker_id]
376 new_project = Project.find(params[:new_project_id])
378 new_project = Project.find(params[:new_project_id])
377 new_tracker = Tracker.find(params[:new_tracker_id])
379 new_tracker = Tracker.find(params[:new_tracker_id])
378 @issues.each { |i|
380 @issues.each { |i|
379 # project dependent properties
381 # project dependent properties
380 unless i.project_id == new_project.id
382 unless i.project_id == new_project.id
381 i.category = nil
383 i.category = nil
382 i.fixed_version = nil
384 i.fixed_version = nil
383 # delete issue relations
385 # delete issue relations
384 i.relations_from.clear
386 i.relations_from.clear
385 i.relations_to.clear
387 i.relations_to.clear
386 end
388 end
387 # move the issue
389 # move the issue
388 i.project = new_project
390 i.project = new_project
389 i.tracker = new_tracker
391 i.tracker = new_tracker
390 i.save
392 i.save
391 }
393 }
392 flash[:notice] = l(:notice_successful_update)
394 flash[:notice] = l(:notice_successful_update)
393 redirect_to :action => 'list_issues', :id => @project
395 redirect_to :action => 'list_issues', :id => @project
394 end
396 end
395 end
397 end
396
398
397 # Add a news to @project
399 # Add a news to @project
398 def add_news
400 def add_news
399 @news = News.new(:project => @project)
401 @news = News.new(:project => @project)
400 if request.post?
402 if request.post?
401 @news.attributes = params[:news]
403 @news.attributes = params[:news]
402 @news.author_id = self.logged_in_user.id if self.logged_in_user
404 @news.author_id = self.logged_in_user.id if self.logged_in_user
403 if @news.save
405 if @news.save
404 flash[:notice] = l(:notice_successful_create)
406 flash[:notice] = l(:notice_successful_create)
405 redirect_to :action => 'list_news', :id => @project
407 redirect_to :action => 'list_news', :id => @project
406 end
408 end
407 end
409 end
408 end
410 end
409
411
410 # Show news list of @project
412 # Show news list of @project
411 def list_news
413 def list_news
412 @news_pages, @news = paginate :news, :per_page => 10, :conditions => ["project_id=?", @project.id], :include => :author, :order => "#{News.table_name}.created_on DESC"
414 @news_pages, @news = paginate :news, :per_page => 10, :conditions => ["project_id=?", @project.id], :include => :author, :order => "#{News.table_name}.created_on DESC"
413 render :action => "list_news", :layout => false if request.xhr?
415 render :action => "list_news", :layout => false if request.xhr?
414 end
416 end
415
417
416 def add_file
418 def add_file
417 if request.post?
419 if request.post?
418 @version = @project.versions.find_by_id(params[:version_id])
420 @version = @project.versions.find_by_id(params[:version_id])
419 # Save the attachments
421 # Save the attachments
420 @attachments = []
422 @attachments = []
421 params[:attachments].each { |file|
423 params[:attachments].each { |file|
422 next unless file.size > 0
424 next unless file.size > 0
423 a = Attachment.create(:container => @version, :file => file, :author => logged_in_user)
425 a = Attachment.create(:container => @version, :file => file, :author => logged_in_user)
424 @attachments << a unless a.new_record?
426 @attachments << a unless a.new_record?
425 } if params[:attachments] and params[:attachments].is_a? Array
427 } if params[:attachments] and params[:attachments].is_a? Array
426 Mailer.deliver_attachments_add(@attachments) if !@attachments.empty? and Permission.find_by_controller_and_action(params[:controller], params[:action]).mail_enabled?
428 Mailer.deliver_attachments_add(@attachments) if !@attachments.empty? and Permission.find_by_controller_and_action(params[:controller], params[:action]).mail_enabled?
427 redirect_to :controller => 'projects', :action => 'list_files', :id => @project
429 redirect_to :controller => 'projects', :action => 'list_files', :id => @project
428 end
430 end
429 @versions = @project.versions.sort
431 @versions = @project.versions.sort
430 end
432 end
431
433
432 def list_files
434 def list_files
433 @versions = @project.versions.sort
435 @versions = @project.versions.sort
434 end
436 end
435
437
436 # Show changelog for @project
438 # Show changelog for @project
437 def changelog
439 def changelog
438 @trackers = Tracker.find(:all, :conditions => ["is_in_chlog=?", true], :order => 'position')
440 @trackers = Tracker.find(:all, :conditions => ["is_in_chlog=?", true], :order => 'position')
439 retrieve_selected_tracker_ids(@trackers)
441 retrieve_selected_tracker_ids(@trackers)
440 @versions = @project.versions.sort
442 @versions = @project.versions.sort
441 end
443 end
442
444
443 def roadmap
445 def roadmap
444 @trackers = Tracker.find(:all, :conditions => ["is_in_roadmap=?", true], :order => 'position')
446 @trackers = Tracker.find(:all, :conditions => ["is_in_roadmap=?", true], :order => 'position')
445 retrieve_selected_tracker_ids(@trackers)
447 retrieve_selected_tracker_ids(@trackers)
446 @versions = @project.versions.sort
448 @versions = @project.versions.sort
447 @versions = @versions.select {|v| !v.completed? } unless params[:completed]
449 @versions = @versions.select {|v| !v.completed? } unless params[:completed]
448 end
450 end
449
451
450 def activity
452 def activity
451 if params[:year] and params[:year].to_i > 1900
453 if params[:year] and params[:year].to_i > 1900
452 @year = params[:year].to_i
454 @year = params[:year].to_i
453 if params[:month] and params[:month].to_i > 0 and params[:month].to_i < 13
455 if params[:month] and params[:month].to_i > 0 and params[:month].to_i < 13
454 @month = params[:month].to_i
456 @month = params[:month].to_i
455 end
457 end
456 end
458 end
457 @year ||= Date.today.year
459 @year ||= Date.today.year
458 @month ||= Date.today.month
460 @month ||= Date.today.month
459
461
460 @date_from = Date.civil(@year, @month, 1)
462 @date_from = Date.civil(@year, @month, 1)
461 @date_to = @date_from >> 1
463 @date_to = @date_from >> 1
462
464
463 @events_by_day = {}
465 @events_by_day = {}
464
466
465 unless params[:show_issues] == "0"
467 unless params[:show_issues] == "0"
466 @project.issues.find(:all, :include => [:author], :conditions => ["#{Issue.table_name}.created_on BETWEEN ? AND ?", @date_from, @date_to] ).each { |i|
468 @project.issues.find(:all, :include => [:author], :conditions => ["#{Issue.table_name}.created_on BETWEEN ? AND ?", @date_from, @date_to] ).each { |i|
467 @events_by_day[i.created_on.to_date] ||= []
469 @events_by_day[i.created_on.to_date] ||= []
468 @events_by_day[i.created_on.to_date] << i
470 @events_by_day[i.created_on.to_date] << i
469 }
471 }
470 @project.issue_changes.find(:all, :include => :details, :conditions => ["(#{Journal.table_name}.created_on BETWEEN ? AND ?) AND (#{JournalDetail.table_name}.prop_key = 'status_id')", @date_from, @date_to] ).each { |i|
472 @project.issue_changes.find(:all, :include => :details, :conditions => ["(#{Journal.table_name}.created_on BETWEEN ? AND ?) AND (#{JournalDetail.table_name}.prop_key = 'status_id')", @date_from, @date_to] ).each { |i|
471 @events_by_day[i.created_on.to_date] ||= []
473 @events_by_day[i.created_on.to_date] ||= []
472 @events_by_day[i.created_on.to_date] << i
474 @events_by_day[i.created_on.to_date] << i
473 }
475 }
474 @show_issues = 1
476 @show_issues = 1
475 end
477 end
476
478
477 unless params[:show_news] == "0"
479 unless params[:show_news] == "0"
478 @project.news.find(:all, :conditions => ["#{News.table_name}.created_on BETWEEN ? AND ?", @date_from, @date_to], :include => :author ).each { |i|
480 @project.news.find(:all, :conditions => ["#{News.table_name}.created_on BETWEEN ? AND ?", @date_from, @date_to], :include => :author ).each { |i|
479 @events_by_day[i.created_on.to_date] ||= []
481 @events_by_day[i.created_on.to_date] ||= []
480 @events_by_day[i.created_on.to_date] << i
482 @events_by_day[i.created_on.to_date] << i
481 }
483 }
482 @show_news = 1
484 @show_news = 1
483 end
485 end
484
486
485 unless params[:show_files] == "0"
487 unless params[:show_files] == "0"
486 Attachment.find(:all, :select => "#{Attachment.table_name}.*",
488 Attachment.find(:all, :select => "#{Attachment.table_name}.*",
487 :joins => "LEFT JOIN #{Version.table_name} ON #{Version.table_name}.id = #{Attachment.table_name}.container_id",
489 :joins => "LEFT JOIN #{Version.table_name} ON #{Version.table_name}.id = #{Attachment.table_name}.container_id",
488 :conditions => ["#{Attachment.table_name}.container_type='Version' and #{Version.table_name}.project_id=? and #{Attachment.table_name}.created_on BETWEEN ? AND ?", @project.id, @date_from, @date_to],
490 :conditions => ["#{Attachment.table_name}.container_type='Version' and #{Version.table_name}.project_id=? and #{Attachment.table_name}.created_on BETWEEN ? AND ?", @project.id, @date_from, @date_to],
489 :include => :author ).each { |i|
491 :include => :author ).each { |i|
490 @events_by_day[i.created_on.to_date] ||= []
492 @events_by_day[i.created_on.to_date] ||= []
491 @events_by_day[i.created_on.to_date] << i
493 @events_by_day[i.created_on.to_date] << i
492 }
494 }
493 @show_files = 1
495 @show_files = 1
494 end
496 end
495
497
496 unless params[:show_documents] == "0"
498 unless params[:show_documents] == "0"
497 @project.documents.find(:all, :conditions => ["#{Document.table_name}.created_on BETWEEN ? AND ?", @date_from, @date_to] ).each { |i|
499 @project.documents.find(:all, :conditions => ["#{Document.table_name}.created_on BETWEEN ? AND ?", @date_from, @date_to] ).each { |i|
498 @events_by_day[i.created_on.to_date] ||= []
500 @events_by_day[i.created_on.to_date] ||= []
499 @events_by_day[i.created_on.to_date] << i
501 @events_by_day[i.created_on.to_date] << i
500 }
502 }
501 Attachment.find(:all, :select => "attachments.*",
503 Attachment.find(:all, :select => "attachments.*",
502 :joins => "LEFT JOIN #{Document.table_name} ON #{Document.table_name}.id = #{Attachment.table_name}.container_id",
504 :joins => "LEFT JOIN #{Document.table_name} ON #{Document.table_name}.id = #{Attachment.table_name}.container_id",
503 :conditions => ["#{Attachment.table_name}.container_type='Document' and #{Document.table_name}.project_id=? and #{Attachment.table_name}.created_on BETWEEN ? AND ?", @project.id, @date_from, @date_to],
505 :conditions => ["#{Attachment.table_name}.container_type='Document' and #{Document.table_name}.project_id=? and #{Attachment.table_name}.created_on BETWEEN ? AND ?", @project.id, @date_from, @date_to],
504 :include => :author ).each { |i|
506 :include => :author ).each { |i|
505 @events_by_day[i.created_on.to_date] ||= []
507 @events_by_day[i.created_on.to_date] ||= []
506 @events_by_day[i.created_on.to_date] << i
508 @events_by_day[i.created_on.to_date] << i
507 }
509 }
508 @show_documents = 1
510 @show_documents = 1
509 end
511 end
510
512
511 unless @project.wiki.nil? || params[:show_wiki_edits] == "0"
513 unless @project.wiki.nil? || params[:show_wiki_edits] == "0"
512 select = "#{WikiContent.versioned_table_name}.updated_on, #{WikiContent.versioned_table_name}.comments, " +
514 select = "#{WikiContent.versioned_table_name}.updated_on, #{WikiContent.versioned_table_name}.comments, " +
513 "#{WikiContent.versioned_table_name}.#{WikiContent.version_column}, #{WikiPage.table_name}.title"
515 "#{WikiContent.versioned_table_name}.#{WikiContent.version_column}, #{WikiPage.table_name}.title"
514 joins = "LEFT JOIN #{WikiPage.table_name} ON #{WikiPage.table_name}.id = #{WikiContent.versioned_table_name}.page_id " +
516 joins = "LEFT JOIN #{WikiPage.table_name} ON #{WikiPage.table_name}.id = #{WikiContent.versioned_table_name}.page_id " +
515 "LEFT JOIN #{Wiki.table_name} ON #{Wiki.table_name}.id = #{WikiPage.table_name}.wiki_id "
517 "LEFT JOIN #{Wiki.table_name} ON #{Wiki.table_name}.id = #{WikiPage.table_name}.wiki_id "
516 conditions = ["#{Wiki.table_name}.project_id = ? AND #{WikiContent.versioned_table_name}.updated_on BETWEEN ? AND ?",
518 conditions = ["#{Wiki.table_name}.project_id = ? AND #{WikiContent.versioned_table_name}.updated_on BETWEEN ? AND ?",
517 @project.id, @date_from, @date_to]
519 @project.id, @date_from, @date_to]
518
520
519 WikiContent.versioned_class.find(:all, :select => select, :joins => joins, :conditions => conditions).each { |i|
521 WikiContent.versioned_class.find(:all, :select => select, :joins => joins, :conditions => conditions).each { |i|
520 # We provide this alias so all events can be treated in the same manner
522 # We provide this alias so all events can be treated in the same manner
521 def i.created_on
523 def i.created_on
522 self.updated_on
524 self.updated_on
523 end
525 end
524
526
525 @events_by_day[i.created_on.to_date] ||= []
527 @events_by_day[i.created_on.to_date] ||= []
526 @events_by_day[i.created_on.to_date] << i
528 @events_by_day[i.created_on.to_date] << i
527 }
529 }
528 @show_wiki_edits = 1
530 @show_wiki_edits = 1
529 end
531 end
530
532
531 unless @project.repository.nil? || params[:show_changesets] == "0"
533 unless @project.repository.nil? || params[:show_changesets] == "0"
532 @project.repository.changesets.find(:all, :conditions => ["#{Changeset.table_name}.committed_on BETWEEN ? AND ?", @date_from, @date_to]).each { |i|
534 @project.repository.changesets.find(:all, :conditions => ["#{Changeset.table_name}.committed_on BETWEEN ? AND ?", @date_from, @date_to]).each { |i|
533 def i.created_on
535 def i.created_on
534 self.committed_on
536 self.committed_on
535 end
537 end
536 @events_by_day[i.created_on.to_date] ||= []
538 @events_by_day[i.created_on.to_date] ||= []
537 @events_by_day[i.created_on.to_date] << i
539 @events_by_day[i.created_on.to_date] << i
538 }
540 }
539 @show_changesets = 1
541 @show_changesets = 1
540 end
542 end
541
543
542 render :layout => false if request.xhr?
544 render :layout => false if request.xhr?
543 end
545 end
544
546
545 def calendar
547 def calendar
546 @trackers = Tracker.find(:all, :order => 'position')
548 @trackers = Tracker.find(:all, :order => 'position')
547 retrieve_selected_tracker_ids(@trackers)
549 retrieve_selected_tracker_ids(@trackers)
548
550
549 if params[:year] and params[:year].to_i > 1900
551 if params[:year] and params[:year].to_i > 1900
550 @year = params[:year].to_i
552 @year = params[:year].to_i
551 if params[:month] and params[:month].to_i > 0 and params[:month].to_i < 13
553 if params[:month] and params[:month].to_i > 0 and params[:month].to_i < 13
552 @month = params[:month].to_i
554 @month = params[:month].to_i
553 end
555 end
554 end
556 end
555 @year ||= Date.today.year
557 @year ||= Date.today.year
556 @month ||= Date.today.month
558 @month ||= Date.today.month
557
559
558 @date_from = Date.civil(@year, @month, 1)
560 @date_from = Date.civil(@year, @month, 1)
559 @date_to = (@date_from >> 1)-1
561 @date_to = (@date_from >> 1)-1
560 # start on monday
562 # start on monday
561 @date_from = @date_from - (@date_from.cwday-1)
563 @date_from = @date_from - (@date_from.cwday-1)
562 # finish on sunday
564 # finish on sunday
563 @date_to = @date_to + (7-@date_to.cwday)
565 @date_to = @date_to + (7-@date_to.cwday)
564
566
565 @events = []
567 @events = []
566 @project.issues_with_subprojects(params[:with_subprojects]) do
568 @project.issues_with_subprojects(params[:with_subprojects]) do
567 @events += Issue.find(:all,
569 @events += Issue.find(:all,
568 :include => [:tracker, :status, :assigned_to, :priority, :project],
570 :include => [:tracker, :status, :assigned_to, :priority, :project],
569 :conditions => ["((start_date>=? and start_date<=?) or (due_date>=? and due_date<=?)) and #{Issue.table_name}.tracker_id in (#{@selected_tracker_ids.join(',')})", @date_from, @date_to, @date_from, @date_to]
571 :conditions => ["((start_date>=? and start_date<=?) or (due_date>=? and due_date<=?)) and #{Issue.table_name}.tracker_id in (#{@selected_tracker_ids.join(',')})", @date_from, @date_to, @date_from, @date_to]
570 ) unless @selected_tracker_ids.empty?
572 ) unless @selected_tracker_ids.empty?
571 end
573 end
572 @events += @project.versions.find(:all, :conditions => ["effective_date BETWEEN ? AND ?", @date_from, @date_to])
574 @events += @project.versions.find(:all, :conditions => ["effective_date BETWEEN ? AND ?", @date_from, @date_to])
573
575
574 @ending_events_by_days = @events.group_by {|event| event.due_date}
576 @ending_events_by_days = @events.group_by {|event| event.due_date}
575 @starting_events_by_days = @events.group_by {|event| event.start_date}
577 @starting_events_by_days = @events.group_by {|event| event.start_date}
576
578
577 render :layout => false if request.xhr?
579 render :layout => false if request.xhr?
578 end
580 end
579
581
580 def gantt
582 def gantt
581 @trackers = Tracker.find(:all, :order => 'position')
583 @trackers = Tracker.find(:all, :order => 'position')
582 retrieve_selected_tracker_ids(@trackers)
584 retrieve_selected_tracker_ids(@trackers)
583
585
584 if params[:year] and params[:year].to_i >0
586 if params[:year] and params[:year].to_i >0
585 @year_from = params[:year].to_i
587 @year_from = params[:year].to_i
586 if params[:month] and params[:month].to_i >=1 and params[:month].to_i <= 12
588 if params[:month] and params[:month].to_i >=1 and params[:month].to_i <= 12
587 @month_from = params[:month].to_i
589 @month_from = params[:month].to_i
588 else
590 else
589 @month_from = 1
591 @month_from = 1
590 end
592 end
591 else
593 else
592 @month_from ||= (Date.today << 1).month
594 @month_from ||= (Date.today << 1).month
593 @year_from ||= (Date.today << 1).year
595 @year_from ||= (Date.today << 1).year
594 end
596 end
595
597
596 @zoom = (params[:zoom].to_i > 0 and params[:zoom].to_i < 5) ? params[:zoom].to_i : 2
598 @zoom = (params[:zoom].to_i > 0 and params[:zoom].to_i < 5) ? params[:zoom].to_i : 2
597 @months = (params[:months].to_i > 0 and params[:months].to_i < 25) ? params[:months].to_i : 6
599 @months = (params[:months].to_i > 0 and params[:months].to_i < 25) ? params[:months].to_i : 6
598
600
599 @date_from = Date.civil(@year_from, @month_from, 1)
601 @date_from = Date.civil(@year_from, @month_from, 1)
600 @date_to = (@date_from >> @months) - 1
602 @date_to = (@date_from >> @months) - 1
601
603
602 @events = []
604 @events = []
603 @project.issues_with_subprojects(params[:with_subprojects]) do
605 @project.issues_with_subprojects(params[:with_subprojects]) do
604 @events += Issue.find(:all,
606 @events += Issue.find(:all,
605 :order => "start_date, due_date",
607 :order => "start_date, due_date",
606 :include => [:tracker, :status, :assigned_to, :priority, :project],
608 :include => [:tracker, :status, :assigned_to, :priority, :project],
607 :conditions => ["(((start_date>=? and start_date<=?) or (due_date>=? and due_date<=?) or (start_date<? and due_date>?)) and start_date is not null and due_date is not null and #{Issue.table_name}.tracker_id in (#{@selected_tracker_ids.join(',')}))", @date_from, @date_to, @date_from, @date_to, @date_from, @date_to]
609 :conditions => ["(((start_date>=? and start_date<=?) or (due_date>=? and due_date<=?) or (start_date<? and due_date>?)) and start_date is not null and due_date is not null and #{Issue.table_name}.tracker_id in (#{@selected_tracker_ids.join(',')}))", @date_from, @date_to, @date_from, @date_to, @date_from, @date_to]
608 ) unless @selected_tracker_ids.empty?
610 ) unless @selected_tracker_ids.empty?
609 end
611 end
610 @events += @project.versions.find(:all, :conditions => ["effective_date BETWEEN ? AND ?", @date_from, @date_to])
612 @events += @project.versions.find(:all, :conditions => ["effective_date BETWEEN ? AND ?", @date_from, @date_to])
611 @events.sort! {|x,y| x.start_date <=> y.start_date }
613 @events.sort! {|x,y| x.start_date <=> y.start_date }
612
614
613 if params[:output]=='pdf'
615 if params[:output]=='pdf'
614 @options_for_rfpdf ||= {}
616 @options_for_rfpdf ||= {}
615 @options_for_rfpdf[:file_name] = "gantt.pdf"
617 @options_for_rfpdf[:file_name] = "gantt.pdf"
616 render :template => "projects/gantt.rfpdf", :layout => false
618 render :template => "projects/gantt.rfpdf", :layout => false
617 else
619 else
618 render :template => "projects/gantt.rhtml"
620 render :template => "projects/gantt.rhtml"
619 end
621 end
620 end
622 end
621
623
622 def feeds
624 def feeds
623 @queries = @project.queries.find :all, :conditions => ["is_public=? or user_id=?", true, (logged_in_user ? logged_in_user.id : 0)]
625 @queries = @project.queries.find :all, :conditions => ["is_public=? or user_id=?", true, (logged_in_user ? logged_in_user.id : 0)]
624 @key = logged_in_user.get_or_create_rss_key.value if logged_in_user
626 @key = logged_in_user.get_or_create_rss_key.value if logged_in_user
625 end
627 end
626
628
627 private
629 private
628 # Find project of id params[:id]
630 # Find project of id params[:id]
629 # if not found, redirect to project list
631 # if not found, redirect to project list
630 # Used as a before_filter
632 # Used as a before_filter
631 def find_project
633 def find_project
632 @project = Project.find(params[:id])
634 @project = Project.find(params[:id])
633 @html_title = @project.name
635 @html_title = @project.name
634 rescue ActiveRecord::RecordNotFound
636 rescue ActiveRecord::RecordNotFound
635 render_404
637 render_404
636 end
638 end
637
639
638 def retrieve_selected_tracker_ids(selectable_trackers)
640 def retrieve_selected_tracker_ids(selectable_trackers)
639 if ids = params[:tracker_ids]
641 if ids = params[:tracker_ids]
640 @selected_tracker_ids = (ids.is_a? Array) ? ids.collect { |id| id.to_i.to_s } : ids.split('/').collect { |id| id.to_i.to_s }
642 @selected_tracker_ids = (ids.is_a? Array) ? ids.collect { |id| id.to_i.to_s } : ids.split('/').collect { |id| id.to_i.to_s }
641 else
643 else
642 @selected_tracker_ids = selectable_trackers.collect {|t| t.id.to_s }
644 @selected_tracker_ids = selectable_trackers.collect {|t| t.id.to_s }
643 end
645 end
644 end
646 end
645
647
646 # Retrieve query from session or build a new query
648 # Retrieve query from session or build a new query
647 def retrieve_query
649 def retrieve_query
648 if params[:query_id]
650 if params[:query_id]
649 @query = @project.queries.find(params[:query_id])
651 @query = @project.queries.find(params[:query_id])
650 @query.executed_by = logged_in_user
652 @query.executed_by = logged_in_user
651 session[:query] = @query
653 session[:query] = @query
652 else
654 else
653 if params[:set_filter] or !session[:query] or session[:query].project_id != @project.id
655 if params[:set_filter] or !session[:query] or session[:query].project_id != @project.id
654 # Give it a name, required to be valid
656 # Give it a name, required to be valid
655 @query = Query.new(:name => "_", :executed_by => logged_in_user)
657 @query = Query.new(:name => "_", :executed_by => logged_in_user)
656 @query.project = @project
658 @query.project = @project
657 if params[:fields] and params[:fields].is_a? Array
659 if params[:fields] and params[:fields].is_a? Array
658 params[:fields].each do |field|
660 params[:fields].each do |field|
659 @query.add_filter(field, params[:operators][field], params[:values][field])
661 @query.add_filter(field, params[:operators][field], params[:values][field])
660 end
662 end
661 else
663 else
662 @query.available_filters.keys.each do |field|
664 @query.available_filters.keys.each do |field|
663 @query.add_short_filter(field, params[field]) if params[field]
665 @query.add_short_filter(field, params[field]) if params[field]
664 end
666 end
665 end
667 end
666 session[:query] = @query
668 session[:query] = @query
667 else
669 else
668 @query = session[:query]
670 @query = session[:query]
669 end
671 end
670 end
672 end
671 end
673 end
672 end
674 end
@@ -1,25 +1,27
1 # redMine - project management software
1 # redMine - project management software
2 # Copyright (C) 2006 Jean-Philippe Lang
2 # Copyright (C) 2006 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 WelcomeController < ApplicationController
18 class WelcomeController < ApplicationController
19 layout 'base'
19 layout 'base'
20
20
21 def index
21 def index
22 @news = News.latest logged_in_user
22 @news = News.latest logged_in_user
23 @projects = Project.latest logged_in_user
23 @projects = Project.latest logged_in_user
24
25 @key = logged_in_user.get_or_create_rss_key.value if logged_in_user
24 end
26 end
25 end
27 end
@@ -1,28 +1,28
1 xml.instruct!
1 xml.instruct!
2 xml.rss "version" => "2.0", "xmlns:dc" => "http://purl.org/dc/elements/1.1/" do
2 xml.rss "version" => "2.0", "xmlns:dc" => "http://purl.org/dc/elements/1.1/" do
3 xml.channel do
3 xml.channel do
4 xml.title @title
4 xml.title @title
5 xml.link url_for(:controller => 'welcome', :only_path => false)
5 xml.link url_for(:controller => 'welcome', :only_path => false)
6 xml.pubDate CGI.rfc1123_date(@journals.first ? @journals.first.created_on : Time.now)
6 xml.pubDate CGI.rfc1123_date(@journals.first ? @journals.first.created_on : Time.now)
7 xml.description l(:label_reported_issues)
7 xml.description l(:label_changes_details)
8 @journals.each do |journal|
8 @journals.each do |journal|
9 issue = journal.issue
9 issue = journal.issue
10 xml.item do
10 xml.item do
11 xml.title "#{issue.project.name} - #{issue.tracker.name} ##{issue.id}: #{issue.subject}"
11 xml.title "#{issue.project.name} - #{issue.tracker.name} ##{issue.id}: #{issue.subject}"
12 url = url_for(:controller => 'issues' , :action => 'show', :id => issue, :only_path => false)
12 url = url_for(:controller => 'issues' , :action => 'show', :id => issue, :only_path => false)
13 xml.link url
13 xml.link url
14 xml.description do
14 xml.description do
15 xml.text! h(journal.notes)
15 xml.text! h(journal.notes)
16 xml.text! "<ul>"
16 xml.text! "<ul>"
17 journal.details.each do |detail|
17 journal.details.each do |detail|
18 xml.text! "<li>" + show_detail(detail, false) + "</li>"
18 xml.text! "<li>" + show_detail(detail, false) + "</li>"
19 end
19 end
20 xml.text! "</ul>"
20 xml.text! "</ul>"
21 end
21 end
22 xml.pubDate CGI.rfc1123_date(journal.created_on)
22 xml.pubDate CGI.rfc1123_date(journal.created_on)
23 xml.guid url
23 xml.guid url
24 xml.author h(journal.user.name)
24 xml.author h(journal.user.name)
25 end
25 end
26 end
26 end
27 end
27 end
28 end No newline at end of file
28 end
@@ -1,20 +1,20
1 xml.instruct!
1 xml.instruct!
2 xml.rss "version" => "2.0", "xmlns:dc" => "http://purl.org/dc/elements/1.1/" do
2 xml.rss "version" => "2.0", "xmlns:dc" => "http://purl.org/dc/elements/1.1/" do
3 xml.channel do
3 xml.channel do
4 xml.title @title
4 xml.title @title
5 xml.link url_for(:controller => 'welcome', :only_path => false)
5 xml.link url_for(:controller => 'welcome', :only_path => false)
6 xml.pubDate CGI.rfc1123_date(@issues.first ? @issues.first.created_on : Time.now)
6 xml.pubDate CGI.rfc1123_date(@issues.first ? @issues.first.created_on : Time.now)
7 xml.description l(:label_reported_issues)
7 xml.description l(:label_reported_issues)
8 @issues.each do |issue|
8 @issues.each do |issue|
9 xml.item do
9 xml.item do
10 xml.title "#{issue.project.name} - #{issue.tracker.name} ##{issue.id}: #{issue.subject}"
10 xml.title "#{issue.project.name} - #{issue.tracker.name} ##{issue.id}: #{issue.subject}"
11 url = url_for(:controller => 'issues' , :action => 'show', :id => issue, :only_path => false)
11 url = url_for(:controller => 'issues' , :action => 'show', :id => issue, :only_path => false)
12 xml.link url
12 xml.link url
13 xml.description h(issue.description)
13 xml.description h(issue.description)
14 xml.pubDate CGI.rfc1123_date(issue.created_on)
14 xml.pubDate CGI.rfc1123_date(issue.created_on)
15 xml.guid url
15 xml.guid url
16 xml.author h(issue.author.name)
16 xml.author h(issue.author.name)
17 end
17 end
18 end
18 end
19 end
19 end
20 end No newline at end of file
20 end
@@ -1,59 +1,70
1 <div class="contextual">
1 <div class="contextual">
2 <%= link_to l(:label_feed_plural), {:action => 'feeds', :id => @project}, :class => 'icon icon-feed' %>
2 <%= link_to l(:label_feed_plural), {:action => 'feeds', :id => @project}, :class => 'icon icon-feed' %>
3 </div>
3 </div>
4
4
5 <h2><%=l(:label_overview)%></h2>
5 <h2><%=l(:label_overview)%></h2>
6
6
7 <div class="splitcontentleft">
7 <div class="splitcontentleft">
8 <%= textilizable @project.description %>
8 <%= textilizable @project.description %>
9 <ul>
9 <ul>
10 <% unless @project.homepage.blank? %><li><%=l(:field_homepage)%>: <%= auto_link @project.homepage %></li><% end %>
10 <% unless @project.homepage.blank? %><li><%=l(:field_homepage)%>: <%= auto_link @project.homepage %></li><% end %>
11 <li><%=l(:field_created_on)%>: <%= format_date(@project.created_on) %></li>
11 <li><%=l(:field_created_on)%>: <%= format_date(@project.created_on) %></li>
12 <% unless @project.parent.nil? %>
12 <% unless @project.parent.nil? %>
13 <li><%=l(:field_parent)%>: <%= link_to @project.parent.name, :controller => 'projects', :action => 'show', :id => @project.parent %></li>
13 <li><%=l(:field_parent)%>: <%= link_to @project.parent.name, :controller => 'projects', :action => 'show', :id => @project.parent %></li>
14 <% end %>
14 <% end %>
15 <% for custom_value in @custom_values %>
15 <% for custom_value in @custom_values %>
16 <% if !custom_value.value.empty? %>
16 <% if !custom_value.value.empty? %>
17 <li><%= custom_value.custom_field.name%>: <%=h show_value(custom_value) %></li>
17 <li><%= custom_value.custom_field.name%>: <%=h show_value(custom_value) %></li>
18 <% end %>
18 <% end %>
19 <% end %>
19 <% end %>
20 </ul>
20 </ul>
21
21
22 <div class="box">
22 <div class="box">
23 <h3 class="icon22 icon22-tracker"><%=l(:label_issue_tracking)%></h3>
23 <h3 class="icon22 icon22-tracker"><%=l(:label_issue_tracking)%></h3>
24 <ul>
24 <ul>
25 <% for tracker in @trackers %>
25 <% for tracker in @trackers %>
26 <li><%= link_to tracker.name, :controller => 'projects', :action => 'list_issues', :id => @project,
26 <li><%= link_to tracker.name, :controller => 'projects', :action => 'list_issues', :id => @project,
27 :set_filter => 1,
27 :set_filter => 1,
28 "tracker_id" => tracker.id %>:
28 "tracker_id" => tracker.id %>:
29 <%= @open_issues_by_tracker[tracker] || 0 %> <%= lwr(:label_open_issues, @open_issues_by_tracker[tracker] || 0) %>
29 <%= @open_issues_by_tracker[tracker] || 0 %> <%= lwr(:label_open_issues, @open_issues_by_tracker[tracker] || 0) %>
30 <%= l(:label_on) %> <%= @total_issues_by_tracker[tracker] || 0 %></li>
30 <%= l(:label_on) %> <%= @total_issues_by_tracker[tracker] || 0 %></li>
31 <% end %>
31 <% end %>
32 </ul>
32 </ul>
33 <p class="textcenter"><small><%= link_to l(:label_issue_view_all), :controller => 'projects', :action => 'list_issues', :id => @project, :set_filter => 1 %></small></p>
33 <p class="textcenter"><small><%= link_to l(:label_issue_view_all), :controller => 'projects', :action => 'list_issues', :id => @project, :set_filter => 1 %></small></p>
34 </div>
34 </div>
35 </div>
35 </div>
36
36
37 <div class="splitcontentright">
37 <div class="splitcontentright">
38 <div class="box">
38 <div class="box">
39 <h3 class="icon22 icon22-users"><%=l(:label_member_plural)%></h3>
39 <h3 class="icon22 icon22-users"><%=l(:label_member_plural)%></h3>
40 <% @members_by_role.keys.sort.each do |role| %>
40 <% @members_by_role.keys.sort.each do |role| %>
41 <%= role.name %>: <%= @members_by_role[role].collect(&:user).sort.collect{|u| link_to_user u}.join(", ") %><br />
41 <%= role.name %>: <%= @members_by_role[role].collect(&:user).sort.collect{|u| link_to_user u}.join(", ") %><br />
42 <% end %>
42 <% end %>
43 </div>
43 </div>
44
44
45 <% if @subprojects.any? %>
45 <% if @subprojects.any? %>
46 <div class="box">
46 <div class="box">
47 <h3 class="icon22 icon22-projects"><%=l(:label_subproject_plural)%></h3>
47 <h3 class="icon22 icon22-projects"><%=l(:label_subproject_plural)%></h3>
48 <%= @subprojects.collect{|p| link_to(p.name, :action => 'show', :id => p)}.join(", ") %>
48 <%= @subprojects.collect{|p| link_to(p.name, :action => 'show', :id => p)}.join(", ") %>
49 </div>
49 </div>
50 <% end %>
50 <% end %>
51
51
52 <% if @news.any? %>
52 <% if @news.any? %>
53 <div class="box">
53 <div class="box">
54 <h3><%=l(:label_news_latest)%></h3>
54 <h3><%=l(:label_news_latest)%></h3>
55 <%= render :partial => 'news/news', :collection => @news %>
55 <%= render :partial => 'news/news', :collection => @news %>
56 <p class="textcenter"><small><%= link_to l(:label_news_view_all), :controller => 'projects', :action => 'list_news', :id => @project %></small></p>
56 <p class="textcenter"><small><%= link_to l(:label_news_view_all), :controller => 'projects', :action => 'list_news', :id => @project %></small></p>
57 </div>
57 </div>
58 <% end %>
58 <% end %>
59 </div> No newline at end of file
59 </div>
60
61 <% content_for :header_tags do %>
62 <%= auto_discovery_link_tag(:rss, {:controller => 'feeds', :action => 'issues', :project_id => @project, :key => @key}, {:title => l(:label_reported_issues)}) %>
63 <%= auto_discovery_link_tag(:atom, {:controller => 'feeds', :action => 'issues', :project_id => @project, :key => @key, :format => 'atom'}, {:title => l(:label_reported_issues)}) %>
64
65 <%= auto_discovery_link_tag(:rss, {:controller => 'feeds', :action => 'history', :project_id => @project, :key => @key }, {:title => l(:label_changes_details)}) %>
66 <%= auto_discovery_link_tag(:atom, {:controller => 'feeds', :action => 'history', :project_id => @project, :key => @key, :format => 'atom'}, {:title => l(:label_changes_details)}) %>
67
68 <%= auto_discovery_link_tag(:rss, {:controller => 'feeds', :action => 'news', :project_id => @project, :key => @key}, {:title => l(:label_news_latest)}) %>
69 <%= auto_discovery_link_tag(:atom, {:controller => 'feeds', :action => 'news', :project_id => @project, :key => @key, :format => 'atom'}, {:title => l(:label_news_latest)}) %>
70 <% end %>
@@ -1,27 +1,28
1 <h2><%= l(:label_home) %></h2>
1 <h2><%= l(:label_home) %></h2>
2
2
3 <div class="splitcontentleft">
3 <div class="splitcontentleft">
4 <p><%= Setting.welcome_text %></p>
4 <p><%= Setting.welcome_text %></p>
5 <div class="box">
5 <div class="box">
6 <h3><%=l(:label_news_latest)%></h3>
6 <h3><%=l(:label_news_latest)%></h3>
7 <%= render :partial => 'news/news', :collection => @news %>
7 <%= render :partial => 'news/news', :collection => @news %>
8 </div>
8 </div>
9 </div>
9 </div>
10
10
11 <div class="splitcontentright">
11 <div class="splitcontentright">
12 <div class="box">
12 <div class="box">
13 <h3 class="icon22 icon22-projects"><%=l(:label_project_latest)%></h3>
13 <h3 class="icon22 icon22-projects"><%=l(:label_project_latest)%></h3>
14 <ul>
14 <ul>
15 <% for project in @projects %>
15 <% for project in @projects %>
16 <li>
16 <li>
17 <%= link_to project.name, :controller => 'projects', :action => 'show', :id => project %> (<%= format_time(project.created_on) %>)<br />
17 <%= link_to project.name, :controller => 'projects', :action => 'show', :id => project %> (<%= format_time(project.created_on) %>)<br />
18 <%=h project.description %>
18 <%=h project.description %>
19 </li>
19 </li>
20 <% end %>
20 <% end %>
21 </ul>
21 </ul>
22 </div>
22 </div>
23 </div>
23 </div>
24
24
25 <% content_for :header_tags do %>
25 <% content_for :header_tags do %>
26 <%= auto_discovery_link_tag(:rss, {:controller => 'feeds' , :action => 'news' }) %>
26 <%= auto_discovery_link_tag(:rss, {:controller => 'feeds', :action => 'news', :key => @key}, {:title => l(:label_news_latest)}) %>
27 <% end %> No newline at end of file
27 <%= auto_discovery_link_tag(:atom, {:controller => 'feeds', :action => 'news', :key => @key, :format => 'atom'}, {:title => l(:label_news_latest)}) %>
28 <% end %>
General Comments 0
You need to be logged in to leave comments. Login now