# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\r
\r
class ProjectsController < ApplicationController\r
- layout 'base'\r
- before_filter :find_project, :authorize, :except => [ :index, :list, :add ]\r
+ layout 'base'\r
+ before_filter :find_project, :authorize, :except => [ :index, :list, :add ]\r
before_filter :require_admin, :only => [ :add, :destroy ]\r
\r
helper :sort\r
- include SortHelper \r
- helper :search_filter\r
- include SearchFilterHelper \r
- helper :custom_fields\r
- include CustomFieldsHelper \r
+ include SortHelper \r
+ helper :search_filter\r
+ include SearchFilterHelper \r
+ helper :custom_fields\r
+ include CustomFieldsHelper \r
\r
- def index
- list
- render :action => 'list'
- end
+ def index
+ list
+ render :action => 'list'
+ end
\r
# Lists public projects
def list\r
end \r
end\r
\r
- # Show issues list of @project\r
- def list_issues\r
- sort_init 'issues.id', 'desc'\r
- sort_update\r
- \r
- search_filter_criteria 'issues.tracker_id', :values => "Tracker.find(:all)"\r
- search_filter_criteria 'issues.priority_id', :values => "Enumeration.find(:all, :conditions => ['opt=?','IPRI'])"\r
- search_filter_criteria 'issues.category_id', :values => "@project.issue_categories"\r
- search_filter_criteria 'issues.status_id', :values => "IssueStatus.find(:all)"\r
- search_filter_criteria 'issues.author_id', :values => "User.find(:all)", :label => "display_name"\r
- search_filter_update if params[:set_filter] or request.post?\r
- \r
- @issue_count = @project.issues.count(search_filter_clause) \r
- @issue_pages = Paginator.new self, @issue_count,\r
- 15,\r
- @params['page'] \r
- @issues = @project.issues.find :all, :order => sort_clause,\r
+ # Show issues list of @project\r
+ def list_issues\r
+ sort_init 'issues.id', 'desc'\r
+ sort_update\r
+\r
+ search_filter_init_list_issues\r
+ search_filter_update if params[:set_filter] or request.post?\r
+\r
+ @issue_count = Issue.count(:include => :status, :conditions => search_filter_clause) \r
+ @issue_pages = Paginator.new self, @issue_count, 15, @params['page'] \r
+ @issues = Issue.find :all, :order => sort_clause,\r
:include => [ :author, :status, :tracker ],\r
:conditions => search_filter_clause,\r
:limit => @issue_pages.items_per_page,\r
:offset => @issue_pages.current.offset \r
- end\r
+ end\r
+\r
+ # Export filtered/sorted issues list to CSV\r
+ def export_issues_csv\r
+ sort_init 'issues.id', 'desc'\r
+ sort_update\r
+\r
+ search_filter_init_list_issues\r
+ \r
+ @issues = Issue.find :all, :order => sort_clause,\r
+ :include => [ :author, :status, :tracker ],\r
+ :conditions => search_filter_clause \r
\r
+ export = StringIO.new\r
+ CSV::Writer.generate(export, ',') do |csv|\r
+ csv << %w(Id Status Tracker Subject Author Created Updated)\r
+ @issues.each do |issue|\r
+ csv << [issue.id, issue.status.name, issue.tracker.name, issue.subject, issue.author.display_name, _('(time)', issue.created_on), _('(time)', issue.updated_on)]\r
+ end\r
+ end\r
+ export.rewind\r
+ send_data(export.read,\r
+ :type => 'text/csv; charset=utf-8; header=present',\r
+ :filename => 'export.csv')\r
+ end\r
+ \r
# Add a news to @project\r
def add_news\r
@news = @project.news.build(params[:news])\r
end\r
\r
# Show news list of @project\r
- def list_news\r
+ def list_news\r
@news_pages, @news = paginate :news, :per_page => 10, :conditions => ["project_id=?", @project.id], :include => :author, :order => "news.created_on DESC"\r
- end\r
+ end\r
\r
def add_file \r
if request.post?\r
@versions = @project.versions\r
end\r
\r
- # Show changelog of @project\r
- def changelog\r
- @fixed_issues = @project.issues.find(:all, \r
- :include => [ :fixed_version, :status, :tracker ], \r
- :conditions => [ "issue_statuses.is_closed=? and trackers.is_in_chlog=? and issues.fixed_version_id is not null", true, true]\r
- )\r
- end\r
+ # Show changelog of @project\r
+ def changelog\r
+ @fixed_issues = @project.issues.find(:all, \r
+ :include => [ :fixed_version, :status, :tracker ], \r
+ :conditions => [ "issue_statuses.is_closed=? and trackers.is_in_chlog=? and issues.fixed_version_id is not null", true, true]\r
+ )\r
+ end\r
\r
private\r
# Find project of id params[:id]\r
\r
module SearchFilterHelper\r
\r
- def search_filter_criteria(field, options = {})\r
- session[:search_filter] ||= {}\r
- session[:search_filter][field] ||= options\r
- # session[:search_filter][field][:values] = options[:values] unless options[:values].nil?\r
- # session[:search_filter][field][:label] = options[:label] unless options[:label].nil?\r
- end\r
+ def search_filter_criteria(name, options = {})\r
+ session[:search_filter] ||= {}\r
+ session[:search_filter][name] ||= {}\r
+ unless session[:search_filter][name][:options] and session[:search_filter][name][:conditions]\r
+ session[:search_filter][name][:options] = []\r
+ session[:search_filter][name][:conditions] = {}\r
+ yield.each { |c|\r
+ session[:search_filter][name][:options] << [c[0], c[1].to_s]\r
+ session[:search_filter][name][:conditions].store(c[1].to_s, c[2])\r
+ }\r
+ end\r
+ end\r
\r
- def search_filter_update\r
- session[:search_filter].each_key {|field| session[:search_filter][field][:value] = params[field] }\r
- #@search_filter[:value] = params[@search_filter[:field]]\r
- end\r
+ def search_filter_update\r
+ session[:search_filter].each_key {|field| session[:search_filter][field][:value] = params[field] }\r
+ end\r
\r
- def search_filter_clause\r
- clause = "1=1"\r
- 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? }\r
- clause\r
- #@search_filter[:field] + "='" + @search_filter[:value] + "'" unless @search_filter[:value].nil? || @search_filter[:value].empty?\r
- end\r
+ def search_filter_clause\r
+ clause = ["issues.project_id=?", @project.id]\r
+ session[:search_filter].each { |k, v|\r
+ v[:value] ||= v[:options][0][1]\r
+ if (!v[:conditions][v[:value]][0].empty?)\r
+ clause[0] = clause[0] + " AND " + v[:conditions][v[:value]][0]\r
+ clause << v[:conditions][v[:value]][1] if !v[:conditions][v[:value]][1].nil?\r
+ end \r
+ }\r
+ clause\r
+ end\r
\r
- def search_filter_tag(field)\r
- option_values = []\r
- #values = eval @search_filter[:values_expr]\r
- option_values = eval session[:search_filter][field][:values]\r
- \r
- content_tag("select", \r
- content_tag("option", "[All]", :value => "") +\r
- options_from_collection_for_select(option_values, \r
- "id",\r
- session[:search_filter][field][:label] || "name",\r
- session[:search_filter][field][:value].to_i\r
- ),\r
- :name => field\r
+ def search_filter_tag(criteria)\r
+ content_tag("select", \r
+ options_for_select(session[:search_filter][criteria][:options], session[:search_filter][criteria][:value]),\r
+ :name => criteria\r
)\r
- end\r
+ end\r
+ \r
+ def search_filter_init_list_issues\r
+ search_filter_criteria('status_id') { \r
+ [ ["[Open]", "O", ["issue_statuses.is_closed=?", false]],\r
+ ["[All]", "A", ["", false]]\r
+ ] + IssueStatus.find(:all).collect {|s| [s.name, s.id, ["issues.status_id=?", s.id]] } \r
+ }\r
+ \r
+ search_filter_criteria('tracker_id') { \r
+ [ ["[All]", "A", ["", false]]\r
+ ] + Tracker.find(:all).collect {|s| [s.name, s.id, ["issues.tracker_id=?", s.id]] } \r
+ }\r
+ \r
+ search_filter_criteria('priority_id') { \r
+ [ ["[All]", "A", ["", false]]\r
+ ] + Enumeration.find(:all, :conditions => ['opt=?','IPRI']).collect {|s| [s.name, s.id, ["issues.priority_id=?", s.id]] } \r
+ }\r
+ \r
+ search_filter_criteria('category_id') { \r
+ [ ["[All]", "A", ["", false]],\r
+ ["[None]", "N", ["issues.category_id is null"]]\r
+ ] + @project.issue_categories.find(:all).collect {|s| [s.name, s.id, ["issues.category_id=?", s.id]] } \r
+ } \r
\r
+ search_filter_criteria('assigned_to_id') { \r
+ [ ["[All]", "A", ["", false]],\r
+ ["[Nobody]", "N", ["issues.assigned_to_id is null"]]\r
+ ] + User.find(:all).collect {|s| [s.display_name, s.id, ["issues.assigned_to_id=?", s.id]] } \r
+ } \r
+ end\r
end
\ No newline at end of file
<form method="post" class="noborder">\r
<table cellpadding=2>\r
<tr>\r
- <td><%=_('Status')%>:<br /><%= search_filter_tag("issues.status_id") %></td>\r
- <td><%=_('Tracker')%>:<br /><%= search_filter_tag("issues.tracker_id") %></td>\r
- <td><%=_('Priority')%>:<br /><%= search_filter_tag("issues.priority_id") %></td>\r
- <td><%=_('Category')%>:<br /><%= search_filter_tag("issues.category_id") %></td>\r
- <td><%=_('Author')%>:<br /><%= search_filter_tag("issues.author_id") %></td>\r
+ <td><%=_('Status')%>:<br /><%= search_filter_tag("status_id") %></td>\r
+ <td><%=_('Tracker')%>:<br /><%= search_filter_tag("tracker_id") %></td>\r
+ <td><%=_('Priority')%>:<br /><%= search_filter_tag("priority_id") %></td>\r
+ <td><%=_('Category')%>:<br /><%= search_filter_tag("category_id") %></td>\r
+ <td><%=_('Assigned to')%>:<br /><%= search_filter_tag("assigned_to_id") %></td>\r
<td valign="bottom">\r
<%= submit_tag _('Apply filter') %>\r
<%= end_form_tag %>\r
<%= end_form_tag %>\r
</td>\r
</tr>\r
- </table>\r
- \r
- \r
- \r
+</table>\r
+ \r
<table border="0" cellspacing="1" cellpadding="2" class="listTableContent">\r
\r
+ <tr><td colspan="7" align="right">\r
+ <small><%= link_to 'Export to CSV', :action => 'export_issues_csv', :id => @project.id %></small>\r
+ </td></tr>\r
+ \r
<tr class="ListHead"> \r
<%= sort_header_tag('issues.id', :caption => '#') %>\r
<%= sort_header_tag('issue_statuses.name', :caption => _('Status')) %>\r
<p>\r
<%= pagination_links_full @issue_pages %>\r
[ <%= @issue_pages.current.first_item %> - <%= @issue_pages.current.last_item %> / <%= @issue_count %> ]\r
- </p>
-
+ </p>
+
\r
<p>
<%= link_to_if_authorized '» ' + _('Report an issue'), :controller => 'projects', :action => 'add_issue', :id => @project %>
<tr style="background-color:#CEE1ED">\r
<td><%= link_to row.name, :controller => 'projects', :action => 'list_issues', :id => @project, \r
:set_filter => 1, \r
- "issues.#{field_name}" => row.id %></td>\r
+ "#{field_name}" => row.id %></td>\r
<% for status in @statuses %>\r
<td align="center"><%= link_to (aggregate data, { field_name => row.id, "status_id" => status.id }), \r
:controller => 'projects', :action => 'list_issues', :id => @project, \r
:set_filter => 1, \r
- "issues.status_id" => status.id, \r
- "issues.#{field_name}" => row.id %></td>\r
+ "status_id" => status.id, \r
+ "#{field_name}" => row.id %></td>\r
<% end %>\r
- <td align="center"><%= aggregate data, { field_name => row.id, "closed" => 0 } %></td>\r
+ <td align="center"><%= link_to (aggregate data, { field_name => row.id, "closed" => 0 }),\r
+ :controller => 'projects', :action => 'list_issues', :id => @project, \r
+ :set_filter => 1, \r
+ "#{field_name}" => row.id,\r
+ "status_id" => "O" %></td>\r
<td align="center"><%= aggregate data, { field_name => row.id, "closed" => 1 } %></td>\r
<td align="center"><%= link_to (aggregate data, { field_name => row.id }),\r
:controller => 'projects', :action => 'list_issues', :id => @project, \r
:set_filter => 1, \r
- "issues.#{field_name}" => row.id %></td> \r
+ "#{field_name}" => row.id,\r
+ "status_id" => "A" %></td> \r
<% end %>\r
</tr>\r
</table>
\ No newline at end of file
http://redmine.sourceforge.net/\r
\r
\r
+== xx/xx/2006\r
+\r
+* More filter options in issues list\r
+* Issues list exportable to CSV\r
+* Fixed: Error on tables creation with PostgreSQL (rev5)\r
+* Fixed: SQL error in "issue reports" view with PostgreSQL (rev5)\r
+\r
+\r
== 06/25/2006 - v0.1.0\r
\r
* multiple users/multiple projects\r