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