##// END OF EJS Templates
git-svn-id: http://redmine.rubyforge.org/svn/trunk@6 e93f8b46-1217-0410-a6f0-8f06a7374b81
Jean-Philippe Lang -
r4:366ca57c36df
parent child
Show More
@@ -1,260 +1,278
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 ProjectsController < ApplicationController
18 class ProjectsController < ApplicationController
19 layout 'base'
19 layout 'base'
20 before_filter :find_project, :authorize, :except => [ :index, :list, :add ]
20 before_filter :find_project, :authorize, :except => [ :index, :list, :add ]
21 before_filter :require_admin, :only => [ :add, :destroy ]
21 before_filter :require_admin, :only => [ :add, :destroy ]
22
22
23 helper :sort
23 helper :sort
24 include SortHelper
24 include SortHelper
25 helper :search_filter
25 helper :search_filter
26 include SearchFilterHelper
26 include SearchFilterHelper
27 helper :custom_fields
27 helper :custom_fields
28 include CustomFieldsHelper
28 include CustomFieldsHelper
29
29
30 def index
30 def index
31 list
31 list
32 render :action => 'list'
32 render :action => 'list'
33 end
33 end
34
34
35 # Lists public projects
35 # Lists public projects
36 def list
36 def list
37 sort_init 'projects.name', 'asc'
37 sort_init 'projects.name', 'asc'
38 sort_update
38 sort_update
39 @project_count = Project.count(["public=?", true])
39 @project_count = Project.count(["public=?", true])
40 @project_pages = Paginator.new self, @project_count,
40 @project_pages = Paginator.new self, @project_count,
41 15,
41 15,
42 @params['page']
42 @params['page']
43 @projects = Project.find :all, :order => sort_clause,
43 @projects = Project.find :all, :order => sort_clause,
44 :conditions => ["public=?", true],
44 :conditions => ["public=?", true],
45 :limit => @project_pages.items_per_page,
45 :limit => @project_pages.items_per_page,
46 :offset => @project_pages.current.offset
46 :offset => @project_pages.current.offset
47 end
47 end
48
48
49 # Add a new project
49 # Add a new project
50 def add
50 def add
51 @custom_fields = CustomField::find_all
51 @custom_fields = CustomField::find_all
52 @project = Project.new(params[:project])
52 @project = Project.new(params[:project])
53 if request.post?
53 if request.post?
54 @project.custom_fields = CustomField.find(@params[:custom_field_ids]) if @params[:custom_field_ids]
54 @project.custom_fields = CustomField.find(@params[:custom_field_ids]) if @params[:custom_field_ids]
55 if @project.save
55 if @project.save
56 flash[:notice] = 'Project was successfully created.'
56 flash[:notice] = 'Project was successfully created.'
57 redirect_to :controller => 'admin', :action => 'projects'
57 redirect_to :controller => 'admin', :action => 'projects'
58 end
58 end
59 end
59 end
60 end
60 end
61
61
62 # Show @project
62 # Show @project
63 def show
63 def show
64 @members = @project.members.find(:all, :include => [:user, :role])
64 @members = @project.members.find(:all, :include => [:user, :role])
65 end
65 end
66
66
67 def settings
67 def settings
68 @custom_fields = CustomField::find_all
68 @custom_fields = CustomField::find_all
69 @issue_category ||= IssueCategory.new
69 @issue_category ||= IssueCategory.new
70 @member ||= @project.members.new
70 @member ||= @project.members.new
71 @roles = Role.find_all
71 @roles = Role.find_all
72 @users = User.find_all - @project.members.find(:all, :include => :user).collect{|m| m.user }
72 @users = User.find_all - @project.members.find(:all, :include => :user).collect{|m| m.user }
73 end
73 end
74
74
75 # Edit @project
75 # Edit @project
76 def edit
76 def edit
77 if request.post?
77 if request.post?
78 @project.custom_fields = CustomField.find(@params[:custom_field_ids]) if @params[:custom_field_ids]
78 @project.custom_fields = CustomField.find(@params[:custom_field_ids]) if @params[:custom_field_ids]
79 if @project.update_attributes(params[:project])
79 if @project.update_attributes(params[:project])
80 flash[:notice] = 'Project was successfully updated.'
80 flash[:notice] = 'Project was successfully updated.'
81 redirect_to :action => 'settings', :id => @project
81 redirect_to :action => 'settings', :id => @project
82 else
82 else
83 settings
83 settings
84 render :action => 'settings'
84 render :action => 'settings'
85 end
85 end
86 end
86 end
87 end
87 end
88
88
89 # Delete @project
89 # Delete @project
90 def destroy
90 def destroy
91 if request.post? and params[:confirm]
91 if request.post? and params[:confirm]
92 @project.destroy
92 @project.destroy
93 redirect_to :controller => 'admin', :action => 'projects'
93 redirect_to :controller => 'admin', :action => 'projects'
94 end
94 end
95 end
95 end
96
96
97 # Add a new issue category to @project
97 # Add a new issue category to @project
98 def add_issue_category
98 def add_issue_category
99 if request.post?
99 if request.post?
100 @issue_category = @project.issue_categories.build(params[:issue_category])
100 @issue_category = @project.issue_categories.build(params[:issue_category])
101 if @issue_category.save
101 if @issue_category.save
102 redirect_to :action => 'settings', :id => @project
102 redirect_to :action => 'settings', :id => @project
103 else
103 else
104 settings
104 settings
105 render :action => 'settings'
105 render :action => 'settings'
106 end
106 end
107 end
107 end
108 end
108 end
109
109
110 # Add a new version to @project
110 # Add a new version to @project
111 def add_version
111 def add_version
112 @version = @project.versions.build(params[:version])
112 @version = @project.versions.build(params[:version])
113 if request.post? and @version.save
113 if request.post? and @version.save
114 redirect_to :action => 'settings', :id => @project
114 redirect_to :action => 'settings', :id => @project
115 end
115 end
116 end
116 end
117
117
118 # Add a new member to @project
118 # Add a new member to @project
119 def add_member
119 def add_member
120 @member = @project.members.build(params[:member])
120 @member = @project.members.build(params[:member])
121 if request.post?
121 if request.post?
122 if @member.save
122 if @member.save
123 flash[:notice] = 'Member was successfully added.'
123 flash[:notice] = 'Member was successfully added.'
124 redirect_to :action => 'settings', :id => @project
124 redirect_to :action => 'settings', :id => @project
125 else
125 else
126 settings
126 settings
127 render :action => 'settings'
127 render :action => 'settings'
128 end
128 end
129 end
129 end
130 end
130 end
131
131
132 # Show members list of @project
132 # Show members list of @project
133 def list_members
133 def list_members
134 @members = @project.members
134 @members = @project.members
135 end
135 end
136
136
137 # Add a new document to @project
137 # Add a new document to @project
138 def add_document
138 def add_document
139 @categories = Enumeration::get_values('DCAT')
139 @categories = Enumeration::get_values('DCAT')
140 @document = @project.documents.build(params[:document])
140 @document = @project.documents.build(params[:document])
141 if request.post?
141 if request.post?
142 # Save the attachment
142 # Save the attachment
143 if params[:attachment][:file].size > 0
143 if params[:attachment][:file].size > 0
144 @attachment = @document.attachments.build(params[:attachment])
144 @attachment = @document.attachments.build(params[:attachment])
145 @attachment.author_id = session[:user].id unless session[:user].nil?
145 @attachment.author_id = session[:user].id unless session[:user].nil?
146 end
146 end
147 if @document.save
147 if @document.save
148 redirect_to :action => 'list_documents', :id => @project
148 redirect_to :action => 'list_documents', :id => @project
149 end
149 end
150 end
150 end
151 end
151 end
152
152
153 # Show documents list of @project
153 # Show documents list of @project
154 def list_documents
154 def list_documents
155 @documents = @project.documents
155 @documents = @project.documents
156 end
156 end
157
157
158 # Add a new issue to @project
158 # Add a new issue to @project
159 def add_issue
159 def add_issue
160 @trackers = Tracker.find(:all)
160 @trackers = Tracker.find(:all)
161 @priorities = Enumeration::get_values('IPRI')
161 @priorities = Enumeration::get_values('IPRI')
162 if request.get?
162 if request.get?
163 @issue = @project.issues.build
163 @issue = @project.issues.build
164 @custom_values = @project.custom_fields_for_issues.collect { |x| CustomValue.new(:custom_field => x) }
164 @custom_values = @project.custom_fields_for_issues.collect { |x| CustomValue.new(:custom_field => x) }
165 else
165 else
166 # Create the issue and set the author
166 # Create the issue and set the author
167 @issue = @project.issues.build(params[:issue])
167 @issue = @project.issues.build(params[:issue])
168 @issue.author = session[:user] unless session[:user].nil?
168 @issue.author = session[:user] unless session[:user].nil?
169 # Create the document if a file was sent
169 # Create the document if a file was sent
170 if params[:attachment][:file].size > 0
170 if params[:attachment][:file].size > 0
171 @attachment = @issue.attachments.build(params[:attachment])
171 @attachment = @issue.attachments.build(params[:attachment])
172 @attachment.author_id = session[:user].id unless session[:user].nil?
172 @attachment.author_id = session[:user].id unless session[:user].nil?
173 end
173 end
174 @custom_values = @project.custom_fields_for_issues.collect { |x| CustomValue.new(:custom_field => x, :value => params["custom_fields"][x.id.to_s]) }
174 @custom_values = @project.custom_fields_for_issues.collect { |x| CustomValue.new(:custom_field => x, :value => params["custom_fields"][x.id.to_s]) }
175 @issue.custom_values = @custom_values
175 @issue.custom_values = @custom_values
176 if @issue.save
176 if @issue.save
177 flash[:notice] = "Issue was successfully added."
177 flash[:notice] = "Issue was successfully added."
178 Mailer.deliver_issue_add(@issue) if Permission.find_by_controller_and_action(@params[:controller], @params[:action]).mail_enabled?
178 Mailer.deliver_issue_add(@issue) if Permission.find_by_controller_and_action(@params[:controller], @params[:action]).mail_enabled?
179 redirect_to :action => 'list_issues', :id => @project
179 redirect_to :action => 'list_issues', :id => @project
180 end
180 end
181 end
181 end
182 end
182 end
183
183
184 # Show issues list of @project
184 # Show issues list of @project
185 def list_issues
185 def list_issues
186 sort_init 'issues.id', 'desc'
186 sort_init 'issues.id', 'desc'
187 sort_update
187 sort_update
188
188
189 search_filter_criteria 'issues.tracker_id', :values => "Tracker.find(:all)"
189 search_filter_init_list_issues
190 search_filter_criteria 'issues.priority_id', :values => "Enumeration.find(:all, :conditions => ['opt=?','IPRI'])"
190 search_filter_update if params[:set_filter] or request.post?
191 search_filter_criteria 'issues.category_id', :values => "@project.issue_categories"
191
192 search_filter_criteria 'issues.status_id', :values => "IssueStatus.find(:all)"
192 @issue_count = Issue.count(:include => :status, :conditions => search_filter_clause)
193 search_filter_criteria 'issues.author_id', :values => "User.find(:all)", :label => "display_name"
193 @issue_pages = Paginator.new self, @issue_count, 15, @params['page']
194 search_filter_update if params[:set_filter] or request.post?
194 @issues = Issue.find :all, :order => sort_clause,
195
196 @issue_count = @project.issues.count(search_filter_clause)
197 @issue_pages = Paginator.new self, @issue_count,
198 15,
199 @params['page']
200 @issues = @project.issues.find :all, :order => sort_clause,
201 :include => [ :author, :status, :tracker ],
195 :include => [ :author, :status, :tracker ],
202 :conditions => search_filter_clause,
196 :conditions => search_filter_clause,
203 :limit => @issue_pages.items_per_page,
197 :limit => @issue_pages.items_per_page,
204 :offset => @issue_pages.current.offset
198 :offset => @issue_pages.current.offset
205 end
199 end
200
201 # Export filtered/sorted issues list to CSV
202 def export_issues_csv
203 sort_init 'issues.id', 'desc'
204 sort_update
205
206 search_filter_init_list_issues
207
208 @issues = Issue.find :all, :order => sort_clause,
209 :include => [ :author, :status, :tracker ],
210 :conditions => search_filter_clause
206
211
212 export = StringIO.new
213 CSV::Writer.generate(export, ',') do |csv|
214 csv << %w(Id Status Tracker Subject Author Created Updated)
215 @issues.each do |issue|
216 csv << [issue.id, issue.status.name, issue.tracker.name, issue.subject, issue.author.display_name, _('(time)', issue.created_on), _('(time)', issue.updated_on)]
217 end
218 end
219 export.rewind
220 send_data(export.read,
221 :type => 'text/csv; charset=utf-8; header=present',
222 :filename => 'export.csv')
223 end
224
207 # Add a news to @project
225 # Add a news to @project
208 def add_news
226 def add_news
209 @news = @project.news.build(params[:news])
227 @news = @project.news.build(params[:news])
210 if request.post?
228 if request.post?
211 @news.author = session[:user] unless session[:user].nil?
229 @news.author = session[:user] unless session[:user].nil?
212 if @news.save
230 if @news.save
213 redirect_to :action => 'list_news', :id => @project
231 redirect_to :action => 'list_news', :id => @project
214 end
232 end
215 end
233 end
216 end
234 end
217
235
218 # Show news list of @project
236 # Show news list of @project
219 def list_news
237 def list_news
220 @news_pages, @news = paginate :news, :per_page => 10, :conditions => ["project_id=?", @project.id], :include => :author, :order => "news.created_on DESC"
238 @news_pages, @news = paginate :news, :per_page => 10, :conditions => ["project_id=?", @project.id], :include => :author, :order => "news.created_on DESC"
221 end
239 end
222
240
223 def add_file
241 def add_file
224 if request.post?
242 if request.post?
225 # Save the attachment
243 # Save the attachment
226 if params[:attachment][:file].size > 0
244 if params[:attachment][:file].size > 0
227 @attachment = @project.versions.find(params[:version_id]).attachments.build(params[:attachment])
245 @attachment = @project.versions.find(params[:version_id]).attachments.build(params[:attachment])
228 @attachment.author_id = session[:user].id unless session[:user].nil?
246 @attachment.author_id = session[:user].id unless session[:user].nil?
229 if @attachment.save
247 if @attachment.save
230 redirect_to :controller => 'projects', :action => 'list_files', :id => @project
248 redirect_to :controller => 'projects', :action => 'list_files', :id => @project
231 end
249 end
232 end
250 end
233 end
251 end
234 @versions = @project.versions
252 @versions = @project.versions
235 end
253 end
236
254
237 def list_files
255 def list_files
238 @versions = @project.versions
256 @versions = @project.versions
239 end
257 end
240
258
241 # Show changelog of @project
259 # Show changelog of @project
242 def changelog
260 def changelog
243 @fixed_issues = @project.issues.find(:all,
261 @fixed_issues = @project.issues.find(:all,
244 :include => [ :fixed_version, :status, :tracker ],
262 :include => [ :fixed_version, :status, :tracker ],
245 :conditions => [ "issue_statuses.is_closed=? and trackers.is_in_chlog=? and issues.fixed_version_id is not null", true, true]
263 :conditions => [ "issue_statuses.is_closed=? and trackers.is_in_chlog=? and issues.fixed_version_id is not null", true, true]
246 )
264 )
247 end
265 end
248
266
249 private
267 private
250 # Find project of id params[:id]
268 # Find project of id params[:id]
251 # if not found, redirect to project list
269 # if not found, redirect to project list
252 # used as a before_filter
270 # used as a before_filter
253 def find_project
271 def find_project
254 @project = Project.find(params[:id])
272 @project = Project.find(params[:id])
255 rescue
273 rescue
256 flash[:notice] = 'Project not found.'
274 flash[:notice] = 'Project not found.'
257 redirect_to :action => 'list'
275 redirect_to :action => 'list'
258 end
276 end
259
277
260 end
278 end
@@ -1,55 +1,85
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 module SearchFilterHelper
18 module SearchFilterHelper
19
19
20 def search_filter_criteria(field, options = {})
20 def search_filter_criteria(name, options = {})
21 session[:search_filter] ||= {}
21 session[:search_filter] ||= {}
22 session[:search_filter][field] ||= options
22 session[:search_filter][name] ||= {}
23 # session[:search_filter][field][:values] = options[:values] unless options[:values].nil?
23 unless session[:search_filter][name][:options] and session[:search_filter][name][:conditions]
24 # session[:search_filter][field][:label] = options[:label] unless options[:label].nil?
24 session[:search_filter][name][:options] = []
25 end
25 session[:search_filter][name][:conditions] = {}
26 yield.each { |c|
27 session[:search_filter][name][:options] << [c[0], c[1].to_s]
28 session[:search_filter][name][:conditions].store(c[1].to_s, c[2])
29 }
30 end
31 end
26
32
27 def search_filter_update
33 def search_filter_update
28 session[:search_filter].each_key {|field| session[:search_filter][field][:value] = params[field] }
34 session[:search_filter].each_key {|field| session[:search_filter][field][:value] = params[field] }
29 #@search_filter[:value] = params[@search_filter[:field]]
35 end
30 end
31
36
32 def search_filter_clause
37 def search_filter_clause
33 clause = "1=1"
38 clause = ["issues.project_id=?", @project.id]
34 session[:search_filter].each {|field, criteria| clause = clause + " AND " + field + "='" + session[:search_filter][field][:value] + "'" unless session[:search_filter][field][:value].nil? || session[:search_filter][field][:value].empty? }
39 session[:search_filter].each { |k, v|
35 clause
40 v[:value] ||= v[:options][0][1]
36 #@search_filter[:field] + "='" + @search_filter[:value] + "'" unless @search_filter[:value].nil? || @search_filter[:value].empty?
41 if (!v[:conditions][v[:value]][0].empty?)
37 end
42 clause[0] = clause[0] + " AND " + v[:conditions][v[:value]][0]
43 clause << v[:conditions][v[:value]][1] if !v[:conditions][v[:value]][1].nil?
44 end
45 }
46 clause
47 end
38
48
39 def search_filter_tag(field)
49 def search_filter_tag(criteria)
40 option_values = []
50 content_tag("select",
41 #values = eval @search_filter[:values_expr]
51 options_for_select(session[:search_filter][criteria][:options], session[:search_filter][criteria][:value]),
42 option_values = eval session[:search_filter][field][:values]
52 :name => criteria
43
44 content_tag("select",
45 content_tag("option", "[All]", :value => "") +
46 options_from_collection_for_select(option_values,
47 "id",
48 session[:search_filter][field][:label] || "name",
49 session[:search_filter][field][:value].to_i
50 ),
51 :name => field
52 )
53 )
53 end
54 end
55
56 def search_filter_init_list_issues
57 search_filter_criteria('status_id') {
58 [ ["[Open]", "O", ["issue_statuses.is_closed=?", false]],
59 ["[All]", "A", ["", false]]
60 ] + IssueStatus.find(:all).collect {|s| [s.name, s.id, ["issues.status_id=?", s.id]] }
61 }
62
63 search_filter_criteria('tracker_id') {
64 [ ["[All]", "A", ["", false]]
65 ] + Tracker.find(:all).collect {|s| [s.name, s.id, ["issues.tracker_id=?", s.id]] }
66 }
67
68 search_filter_criteria('priority_id') {
69 [ ["[All]", "A", ["", false]]
70 ] + Enumeration.find(:all, :conditions => ['opt=?','IPRI']).collect {|s| [s.name, s.id, ["issues.priority_id=?", s.id]] }
71 }
72
73 search_filter_criteria('category_id') {
74 [ ["[All]", "A", ["", false]],
75 ["[None]", "N", ["issues.category_id is null"]]
76 ] + @project.issue_categories.find(:all).collect {|s| [s.name, s.id, ["issues.category_id=?", s.id]] }
77 }
54
78
79 search_filter_criteria('assigned_to_id') {
80 [ ["[All]", "A", ["", false]],
81 ["[Nobody]", "N", ["issues.assigned_to_id is null"]]
82 ] + User.find(:all).collect {|s| [s.display_name, s.id, ["issues.assigned_to_id=?", s.id]] }
83 }
84 end
55 end No newline at end of file
85 end
@@ -1,56 +1,58
1 <h2><%=_('Issues')%></h2>
1 <h2><%=_('Issues')%></h2>
2
2
3 <form method="post" class="noborder">
3 <form method="post" class="noborder">
4 <table cellpadding=2>
4 <table cellpadding=2>
5 <tr>
5 <tr>
6 <td><%=_('Status')%>:<br /><%= search_filter_tag("issues.status_id") %></td>
6 <td><%=_('Status')%>:<br /><%= search_filter_tag("status_id") %></td>
7 <td><%=_('Tracker')%>:<br /><%= search_filter_tag("issues.tracker_id") %></td>
7 <td><%=_('Tracker')%>:<br /><%= search_filter_tag("tracker_id") %></td>
8 <td><%=_('Priority')%>:<br /><%= search_filter_tag("issues.priority_id") %></td>
8 <td><%=_('Priority')%>:<br /><%= search_filter_tag("priority_id") %></td>
9 <td><%=_('Category')%>:<br /><%= search_filter_tag("issues.category_id") %></td>
9 <td><%=_('Category')%>:<br /><%= search_filter_tag("category_id") %></td>
10 <td><%=_('Author')%>:<br /><%= search_filter_tag("issues.author_id") %></td>
10 <td><%=_('Assigned to')%>:<br /><%= search_filter_tag("assigned_to_id") %></td>
11 <td valign="bottom">
11 <td valign="bottom">
12 <%= submit_tag _('Apply filter') %>
12 <%= submit_tag _('Apply filter') %>
13 <%= end_form_tag %>
13 <%= end_form_tag %>
14
14
15 <%= start_form_tag %>
15 <%= start_form_tag %>
16 <%= submit_tag _('Reset') %>
16 <%= submit_tag _('Reset') %>
17 <%= end_form_tag %>
17 <%= end_form_tag %>
18 </td>
18 </td>
19 </tr>
19 </tr>
20 </table>
20 </table>
21
21 &nbsp;
22 &nbsp;
23
24 <table border="0" cellspacing="1" cellpadding="2" class="listTableContent">
22 <table border="0" cellspacing="1" cellpadding="2" class="listTableContent">
25
23
24 <tr><td colspan="7" align="right">
25 <small><%= link_to 'Export to CSV', :action => 'export_issues_csv', :id => @project.id %></small>
26 </td></tr>
27
26 <tr class="ListHead">
28 <tr class="ListHead">
27 <%= sort_header_tag('issues.id', :caption => '#') %>
29 <%= sort_header_tag('issues.id', :caption => '#') %>
28 <%= sort_header_tag('issue_statuses.name', :caption => _('Status')) %>
30 <%= sort_header_tag('issue_statuses.name', :caption => _('Status')) %>
29 <%= sort_header_tag('issues.tracker_id', :caption => _('Tracker')) %>
31 <%= sort_header_tag('issues.tracker_id', :caption => _('Tracker')) %>
30 <th><%=_('Subject')%></th>
32 <th><%=_('Subject')%></th>
31 <%= sort_header_tag('users.lastname', :caption => _('Author')) %>
33 <%= sort_header_tag('users.lastname', :caption => _('Author')) %>
32 <%= sort_header_tag('issues.created_on', :caption => _('Created on')) %>
34 <%= sort_header_tag('issues.created_on', :caption => _('Created on')) %>
33 <%= sort_header_tag('issues.updated_on', :caption => _('Last update')) %>
35 <%= sort_header_tag('issues.updated_on', :caption => _('Last update')) %>
34 </tr>
36 </tr>
35
37
36 <% for issue in @issues %>
38 <% for issue in @issues %>
37 <tr bgcolor="#<%= issue.status.html_color %>">
39 <tr bgcolor="#<%= issue.status.html_color %>">
38 <td align="center"><%= link_to issue.long_id, :controller => 'issues', :action => 'show', :id => issue %></td>
40 <td align="center"><%= link_to issue.long_id, :controller => 'issues', :action => 'show', :id => issue %></td>
39 <td align="center"><%= issue.status.name %></td>
41 <td align="center"><%= issue.status.name %></td>
40 <td align="center"><%= issue.tracker.name %></td>
42 <td align="center"><%= issue.tracker.name %></td>
41 <td><%= link_to issue.subject, :controller => 'issues', :action => 'show', :id => issue %></td>
43 <td><%= link_to issue.subject, :controller => 'issues', :action => 'show', :id => issue %></td>
42 <td align="center"><%= issue.author.display_name %></td>
44 <td align="center"><%= issue.author.display_name %></td>
43 <td align="center"><%= format_time(issue.created_on) %></td>
45 <td align="center"><%= format_time(issue.created_on) %></td>
44 <td align="center"><%= format_time(issue.updated_on) %></td>
46 <td align="center"><%= format_time(issue.updated_on) %></td>
45 </tr>
47 </tr>
46 <% end %>
48 <% end %>
47 </table>
49 </table>
48 <p>
50 <p>
49 <%= pagination_links_full @issue_pages %>
51 <%= pagination_links_full @issue_pages %>
50 [ <%= @issue_pages.current.first_item %> - <%= @issue_pages.current.last_item %> / <%= @issue_count %> ]
52 [ <%= @issue_pages.current.first_item %> - <%= @issue_pages.current.last_item %> / <%= @issue_count %> ]
51 </p>
53 </p>
52
54
53
55
54 <p>
56 <p>
55 <%= link_to_if_authorized '&#187; ' + _('Report an issue'), :controller => 'projects', :action => 'add_issue', :id => @project %>
57 <%= link_to_if_authorized '&#187; ' + _('Report an issue'), :controller => 'projects', :action => 'add_issue', :id => @project %>
56 </p> No newline at end of file
58 </p>
@@ -1,34 +1,39
1 <% col_width = 70 / (@statuses.length+3) %>
1 <% col_width = 70 / (@statuses.length+3) %>
2
2
3 <table border="0" cellspacing="1" cellpadding="2" width="100%">
3 <table border="0" cellspacing="1" cellpadding="2" width="100%">
4 <tr>
4 <tr>
5 <td width="25%"></td>
5 <td width="25%"></td>
6 <% for status in @statuses %>
6 <% for status in @statuses %>
7 <td align="center" width="<%= col_width %>%" bgcolor="#<%= status.html_color %>"><small><%= status.name %></small></td>
7 <td align="center" width="<%= col_width %>%" bgcolor="#<%= status.html_color %>"><small><%= status.name %></small></td>
8 <% end %>
8 <% end %>
9 <td align="center" width="<%= col_width %>%"><strong><%=_('Open')%></strong></td>
9 <td align="center" width="<%= col_width %>%"><strong><%=_('Open')%></strong></td>
10 <td align="center" width="<%= col_width %>%"><strong><%=_('Closed')%></strong></td>
10 <td align="center" width="<%= col_width %>%"><strong><%=_('Closed')%></strong></td>
11 <td align="center" width="<%= col_width %>%"><strong><%=_('Total')%></strong></td>
11 <td align="center" width="<%= col_width %>%"><strong><%=_('Total')%></strong></td>
12 </tr>
12 </tr>
13
13
14 <% for row in rows %>
14 <% for row in rows %>
15 <tr style="background-color:#CEE1ED">
15 <tr style="background-color:#CEE1ED">
16 <td><%= link_to row.name, :controller => 'projects', :action => 'list_issues', :id => @project,
16 <td><%= link_to row.name, :controller => 'projects', :action => 'list_issues', :id => @project,
17 :set_filter => 1,
17 :set_filter => 1,
18 "issues.#{field_name}" => row.id %></td>
18 "#{field_name}" => row.id %></td>
19 <% for status in @statuses %>
19 <% for status in @statuses %>
20 <td align="center"><%= link_to (aggregate data, { field_name => row.id, "status_id" => status.id }),
20 <td align="center"><%= link_to (aggregate data, { field_name => row.id, "status_id" => status.id }),
21 :controller => 'projects', :action => 'list_issues', :id => @project,
21 :controller => 'projects', :action => 'list_issues', :id => @project,
22 :set_filter => 1,
22 :set_filter => 1,
23 "issues.status_id" => status.id,
23 "status_id" => status.id,
24 "issues.#{field_name}" => row.id %></td>
24 "#{field_name}" => row.id %></td>
25 <% end %>
25 <% end %>
26 <td align="center"><%= aggregate data, { field_name => row.id, "closed" => 0 } %></td>
26 <td align="center"><%= link_to (aggregate data, { field_name => row.id, "closed" => 0 }),
27 :controller => 'projects', :action => 'list_issues', :id => @project,
28 :set_filter => 1,
29 "#{field_name}" => row.id,
30 "status_id" => "O" %></td>
27 <td align="center"><%= aggregate data, { field_name => row.id, "closed" => 1 } %></td>
31 <td align="center"><%= aggregate data, { field_name => row.id, "closed" => 1 } %></td>
28 <td align="center"><%= link_to (aggregate data, { field_name => row.id }),
32 <td align="center"><%= link_to (aggregate data, { field_name => row.id }),
29 :controller => 'projects', :action => 'list_issues', :id => @project,
33 :controller => 'projects', :action => 'list_issues', :id => @project,
30 :set_filter => 1,
34 :set_filter => 1,
31 "issues.#{field_name}" => row.id %></td>
35 "#{field_name}" => row.id,
36 "status_id" => "A" %></td>
32 <% end %>
37 <% end %>
33 </tr>
38 </tr>
34 </table> No newline at end of file
39 </table>
@@ -1,17 +1,25
1 == redMine changelog
1 == redMine changelog
2
2
3 redMine - project management software
3 redMine - project management software
4 Copyright (C) 2006 Jean-Philippe Lang
4 Copyright (C) 2006 Jean-Philippe Lang
5 http://redmine.sourceforge.net/
5 http://redmine.sourceforge.net/
6
6
7
7
8 == xx/xx/2006
9
10 * More filter options in issues list
11 * Issues list exportable to CSV
12 * Fixed: Error on tables creation with PostgreSQL (rev5)
13 * Fixed: SQL error in "issue reports" view with PostgreSQL (rev5)
14
15
8 == 06/25/2006 - v0.1.0
16 == 06/25/2006 - v0.1.0
9
17
10 * multiple users/multiple projects
18 * multiple users/multiple projects
11 * role based access control
19 * role based access control
12 * issue tracking system
20 * issue tracking system
13 * fully customizable workflow
21 * fully customizable workflow
14 * documents/files repository
22 * documents/files repository
15 * email notifications on issue creation and update
23 * email notifications on issue creation and update
16 * multilanguage support (except for error messages):english, french, spanish
24 * multilanguage support (except for error messages):english, french, spanish
17 * online manual in french (unfinished) No newline at end of file
25 * online manual in french (unfinished)
General Comments 0
You need to be logged in to leave comments. Login now