query model/controller added
git-svn-id: http://redmine.rubyforge.org/svn/branches/work@79 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
1 parent
d5192b82aa
commit
da91e5e95a
12 files changed
+333
-25
No files matched your search
@@ -208,8 +208,10 @@ class ProjectsController < ApplicationController
|
|||||||
sort_init 'issues.id', 'desc'
|
sort_init 'issues.id', 'desc'
|
||||||
sort_update
|
sort_update
|
||||||
|
|
||||||
search_filter_init_list_issues
|
@query = Query.new
|
||||||
search_filter_update if params[:set_filter]
|
params[:fields].each do |field|
|
||||||
|
@query.add_filter(field, params[:operators][field], params[:values][field])
|
||||||
|
end if params[:fields]
|
||||||
|
|
||||||
@results_per_page_options = [ 15, 25, 50, 100 ]
|
@results_per_page_options = [ 15, 25, 50, 100 ]
|
||||||
if params[:per_page] and @results_per_page_options.include? params[:per_page].to_i
|
if params[:per_page] and @results_per_page_options.include? params[:per_page].to_i
|
||||||
@@ -219,11 +221,11 @@ class ProjectsController < ApplicationController
|
|||||||
@results_per_page = session[:results_per_page] || 25
|
@results_per_page = session[:results_per_page] || 25
|
||||||
end
|
end
|
||||||
|
|
||||||
@issue_count = Issue.count(:include => [:status, :project], :conditions => search_filter_clause)
|
@issue_count = Issue.count(:include => [:status, :project], :conditions => @query.statement)
|
||||||
@issue_pages = Paginator.new self, @issue_count, @results_per_page, @params['page']
|
@issue_pages = Paginator.new self, @issue_count, @results_per_page, @params['page']
|
||||||
@issues = Issue.find :all, :order => sort_clause,
|
@issues = Issue.find :all, :order => sort_clause,
|
||||||
:include => [ :author, :status, :tracker, :project ],
|
:include => [ :author, :status, :tracker, :project ],
|
||||||
:conditions => search_filter_clause,
|
:conditions => @query.statement,
|
||||||
:limit => @issue_pages.items_per_page,
|
:limit => @issue_pages.items_per_page,
|
||||||
:offset => @issue_pages.current.offset
|
:offset => @issue_pages.current.offset
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
class QueriesController < ApplicationController
|
||||||
|
layout 'base'
|
||||||
|
|
||||||
|
def index
|
||||||
|
list
|
||||||
|
render :action => 'list'
|
||||||
|
end
|
||||||
|
|
||||||
|
# GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
|
||||||
|
verify :method => :post, :only => [ :destroy, :create, :update ],
|
||||||
|
:redirect_to => { :action => :list }
|
||||||
|
|
||||||
|
def list
|
||||||
|
@query_pages, @queries = paginate :queries, :per_page => 10
|
||||||
|
end
|
||||||
|
|
||||||
|
def show
|
||||||
|
@query = Query.find(params[:id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def new
|
||||||
|
@query = Query.new(params[:query])
|
||||||
|
|
||||||
|
params[:fields].each do |field|
|
||||||
|
@query.add_filter(field, params[:operators][field], params[:values][field])
|
||||||
|
end if params[:fields]
|
||||||
|
|
||||||
|
if request.post? and @query.save
|
||||||
|
flash[:notice] = 'Query was successfully created.'
|
||||||
|
redirect_to :action => 'list'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
@query = Query.find(params[:id])
|
||||||
|
|
||||||
|
if request.post?
|
||||||
|
@query.filters = {}
|
||||||
|
params[:fields].each do |field|
|
||||||
|
@query.add_filter(field, params[:operators][field], params[:values][field])
|
||||||
|
end if params[:fields]
|
||||||
|
@query.attributes = params[:query]
|
||||||
|
|
||||||
|
if @query.save
|
||||||
|
flash[:notice] = 'Query was successfully updated.'
|
||||||
|
redirect_to :action => 'show', :id => @query
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
Query.find(params[:id]).destroy
|
||||||
|
redirect_to :action => 'list'
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
module QueriesHelper
|
||||||
|
end
|
||||||
@@ -0,0 +1,123 @@
|
|||||||
|
class Query < ActiveRecord::Base
|
||||||
|
serialize :filters
|
||||||
|
|
||||||
|
validates_presence_of :name
|
||||||
|
|
||||||
|
@@operators = { "=" => "Egal",
|
||||||
|
"!" => "Different",
|
||||||
|
"o" => "Ouvert",
|
||||||
|
"c" => "Ferme",
|
||||||
|
"!*" => "Aucun",
|
||||||
|
"*" => "Tous",
|
||||||
|
"<t+" => "Dans moins de",
|
||||||
|
">t+" => "Dans plus de",
|
||||||
|
"t+" => "Dans exactement",
|
||||||
|
"t" => "Aujourd'hui",
|
||||||
|
">t-" => "Il y a moins de",
|
||||||
|
"<t-" => "Il y a plus de",
|
||||||
|
"t-" => "Il y a exactement" }
|
||||||
|
|
||||||
|
@@operators_by_filter_type = { :list => [ "=", "!" ],
|
||||||
|
:list_status => [ "o", "=", "!", "c" ],
|
||||||
|
:list_optional => [ "=", "!", "!*", "*" ],
|
||||||
|
:date => [ "<t+", ">t+", "t+", "t", ">t-", "<t-", "t-" ],
|
||||||
|
:date_past => [ ">t-", "<t-", "t-", "t" ] }
|
||||||
|
|
||||||
|
@@available_filters = { "status_id" => { :type => :list_status, :order => 1,
|
||||||
|
:values => IssueStatus.find(:all).collect{|s| [s.name, s.id.to_s] } },
|
||||||
|
"tracker_id" => { :type => :list, :order => 2,
|
||||||
|
:values => Tracker.find(:all).collect{|s| [s.name, s.id.to_s] } },
|
||||||
|
"assigned_to_id" => { :type => :list_optional, :order => 3,
|
||||||
|
:values => User.find(:all).collect{|s| [s.display_name, s.id.to_s] } },
|
||||||
|
"priority_id" => { :type => :list, :order => 4,
|
||||||
|
:values => Enumeration.find(:all, :conditions => ['opt=?','IPRI']).collect{|s| [s.name, s.id.to_s] } },
|
||||||
|
"created_on" => { :type => :date_past, :order => 5 },
|
||||||
|
"updated_on" => { :type => :date_past, :order => 6 },
|
||||||
|
"start_date" => { :type => :date, :order => 7 },
|
||||||
|
"due_date" => { :type => :date, :order => 8 } }
|
||||||
|
|
||||||
|
cattr_accessor :available_filters
|
||||||
|
|
||||||
|
def initialize(attributes = nil)
|
||||||
|
super
|
||||||
|
self.filters ||= { 'status_id' => {:operator => "o"} }
|
||||||
|
end
|
||||||
|
|
||||||
|
def validate
|
||||||
|
errors.add_to_base "Au moins un critere doit etre selectionne" unless filters && !filters.empty?
|
||||||
|
filters.each_key do |field|
|
||||||
|
errors.add field.gsub(/\_id$/, ""), "doit etre renseigne" unless
|
||||||
|
# filter requires one or more values
|
||||||
|
(values_for(field) and !values_for(field).first.empty?) or
|
||||||
|
# filter doesn't require any value
|
||||||
|
["o", "c", "!*", "*", "t"].include? operator_for(field)
|
||||||
|
end if filters
|
||||||
|
end
|
||||||
|
|
||||||
|
def add_filter(field, operator, values)
|
||||||
|
# values must be an array
|
||||||
|
return unless values and values.is_a? Array
|
||||||
|
# check if field is defined as an available filter
|
||||||
|
if @@available_filters.has_key? field
|
||||||
|
filter_options = @@available_filters[field]
|
||||||
|
# check if operator is allowed for that filter
|
||||||
|
if @@operators_by_filter_type[filter_options[:type]].include? operator
|
||||||
|
filters[field] = {:operator => operator, :values => values }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def has_filter?(field)
|
||||||
|
filters and filters[field]
|
||||||
|
end
|
||||||
|
|
||||||
|
def operator_for(field)
|
||||||
|
has_filter?(field) ? filters[field][:operator] : nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def values_for(field)
|
||||||
|
has_filter?(field) ? filters[field][:values] : nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def statement
|
||||||
|
sql = "1=1"
|
||||||
|
filters.each_key do |field|
|
||||||
|
sql = sql + " AND " unless sql.empty?
|
||||||
|
v = values_for field
|
||||||
|
case operator_for field
|
||||||
|
when "="
|
||||||
|
sql = sql + "issues.#{field} IN (" + v.each(&:to_i).join(",") + ")"
|
||||||
|
when "!"
|
||||||
|
sql = sql + "issues.#{field} NOT IN (" + v.each(&:to_i).join(",") + ")"
|
||||||
|
when "!*"
|
||||||
|
sql = sql + "issues.#{field} IS NULL"
|
||||||
|
when "*"
|
||||||
|
sql = sql + "issues.#{field} IS NOT NULL"
|
||||||
|
when "o"
|
||||||
|
sql = sql + "issue_statuses.is_closed=#{connection.quoted_false}" if field == "status_id"
|
||||||
|
when "c"
|
||||||
|
sql = sql + "issue_statuses.is_closed=#{connection.quoted_true}" if field == "status_id"
|
||||||
|
when ">t-"
|
||||||
|
sql = sql + "issues.#{field} >= '%s'" % connection.quoted_date(Date.today - v.first.to_i)
|
||||||
|
when "<t-"
|
||||||
|
sql = sql + "issues.#{field} <= '" + (Date.today - v.first.to_i).strftime("%Y-%m-%d") + "'"
|
||||||
|
when "t-"
|
||||||
|
sql = sql + "issues.#{field} = '" + (Date.today - v.first.to_i).strftime("%Y-%m-%d") + "'"
|
||||||
|
when ">t+"
|
||||||
|
sql = sql + "issues.#{field} >= '" + (Date.today + v.first.to_i).strftime("%Y-%m-%d") + "'"
|
||||||
|
when "<t+"
|
||||||
|
sql = sql + "issues.#{field} <= '" + (Date.today + v.first.to_i).strftime("%Y-%m-%d") + "'"
|
||||||
|
when "t+"
|
||||||
|
sql = sql + "issues.#{field} = '" + (Date.today + v.first.to_i).strftime("%Y-%m-%d") + "'"
|
||||||
|
when "t"
|
||||||
|
sql = sql + "issues.#{field} = '%s'" % connection.quoted_date(Date.today)
|
||||||
|
end
|
||||||
|
end if filters
|
||||||
|
sql
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.operators_for_select(filter_type)
|
||||||
|
@@operators_by_filter_type[filter_type].collect {|o| [@@operators[o], o]}
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
@@ -7,28 +7,12 @@
|
|||||||
</small>
|
</small>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
<%= start_form_tag :action => 'list_issues' %>
|
<%= start_form_tag :action => 'list_issues' %>
|
||||||
<table cellpadding=2>
|
<%= render :partial => 'queries/filters', :locals => {:query => @query} %>
|
||||||
<tr>
|
<%= submit_tag l(:button_apply), :class => "button-small" %>
|
||||||
<td valign="bottom"><small><%=l(:field_status)%>:</small><br /><%= search_filter_tag 'status_id', :class => 'select-small' %></td>
|
|
||||||
<td valign="bottom"><small><%=l(:field_tracker)%>:</small><br /><%= search_filter_tag 'tracker_id', :class => 'select-small' %></td>
|
|
||||||
<td valign="bottom"><small><%=l(:field_priority)%>:</small><br /><%= search_filter_tag 'priority_id', :class => 'select-small' %></td>
|
|
||||||
<td valign="bottom"><small><%=l(:field_category)%>:</small><br /><%= search_filter_tag 'category_id', :class => 'select-small' %></td>
|
|
||||||
<td valign="bottom"><small><%=l(:field_fixed_version)%>:</small><br /><%= search_filter_tag 'fixed_version_id', :class => 'select-small' %></td>
|
|
||||||
<td valign="bottom"><small><%=l(:field_author)%>:</small><br /><%= search_filter_tag 'author_id', :class => 'select-small' %></td>
|
|
||||||
<td valign="bottom"><small><%=l(:field_assigned_to)%>:</small><br /><%= search_filter_tag 'assigned_to_id', :class => 'select-small' %></td>
|
|
||||||
<td valign="bottom"><small><%=l(:label_subproject_plural)%>:</small><br /><%= search_filter_tag 'subproject_id', :class => 'select-small' %></td>
|
|
||||||
<td valign="bottom">
|
|
||||||
<%= hidden_field_tag 'set_filter', 1 %>
|
|
||||||
<%= submit_tag l(:button_apply), :class => 'button-small' %>
|
|
||||||
</td>
|
|
||||||
<td valign="bottom">
|
|
||||||
<%= link_to l(:button_clear), :action => 'list_issues', :id => @project, :set_filter => 1 %>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
<%= end_form_tag %>
|
<%= end_form_tag %>
|
||||||
|
</div>
|
||||||
|
|
||||||
<table class="listTableContent">
|
<table class="listTableContent">
|
||||||
<tr>
|
<tr>
|
||||||
|
|||||||
@@ -0,0 +1,72 @@
|
|||||||
|
<script>
|
||||||
|
|
||||||
|
function toggle_filter(field) {
|
||||||
|
check_box = $('cb_' + field);
|
||||||
|
|
||||||
|
if (check_box.checked) {
|
||||||
|
Element.show("operators[" + field + "]");
|
||||||
|
toggle_operator(field);
|
||||||
|
} else {
|
||||||
|
Element.hide("operators[" + field + "]");
|
||||||
|
Element.hide("values_div[" + field + "]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggle_operator(field) {
|
||||||
|
operator = $("operators[" + field + "]");
|
||||||
|
switch (operator.value) {
|
||||||
|
case "!*":
|
||||||
|
case "*":
|
||||||
|
case "t":
|
||||||
|
case "o":
|
||||||
|
case "c":
|
||||||
|
Element.hide("values_div[" + field + "]");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Element.show("values_div[" + field + "]");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggle_multi_select(field) {
|
||||||
|
select = $('values[' + field + '][]');
|
||||||
|
if (select.multiple == true) {
|
||||||
|
select.multiple = false;
|
||||||
|
} else {
|
||||||
|
select.multiple = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<fieldset><legend>Filtres</legend>
|
||||||
|
<table>
|
||||||
|
<% Query.available_filters.sort{|a,b| a[1][:order]<=>b[1][:order]}.each do |filter| %>
|
||||||
|
<% field = filter[0]
|
||||||
|
options = filter[1] %>
|
||||||
|
<tr>
|
||||||
|
<td valign="top" width="200">
|
||||||
|
<%= check_box_tag 'fields[]', field, query.has_filter?(field), :onclick => "toggle_filter('#{field}');", :id => "cb_#{field}" %>
|
||||||
|
<label for="cb_<%= field %>"><%= l(("field_"+field.to_s.gsub(/\_id$/, "")).to_sym) %></label>
|
||||||
|
</td>
|
||||||
|
<td valign="top" width="150">
|
||||||
|
<%= select_tag "operators[#{field}]", options_for_select(Query.operators_for_select(options[:type]), query.operator_for(field)), :onchange => "toggle_operator('#{field}');", :class => "select-small", :style => "vertical-align: top;" %>
|
||||||
|
</td>
|
||||||
|
<td valign="top">
|
||||||
|
<div id="values_div[<%= field %>]">
|
||||||
|
<% case options[:type]
|
||||||
|
when :list, :list_optional, :list_status %>
|
||||||
|
<select <%= "multiple=true" if query.values_for(field) and query.values_for(field).length > 1 %>" name="values[<%= field %>][]" id="values[<%= field %>][]" class="select-small" style="vertical-align: top;">
|
||||||
|
<%= options_for_select options[:values], query.values_for(field) %>
|
||||||
|
</select>
|
||||||
|
<%= link_to_function '+', "toggle_multi_select('#{field}');" %>
|
||||||
|
<% when :date, :date_past %>
|
||||||
|
<%= text_field_tag "values[#{field}][]", query.values_for(field), :size => 3, :class => "select-small" %> jours
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<script>toggle_filter('<%= field %>');</script>
|
||||||
|
<% end %>
|
||||||
|
</table>
|
||||||
|
</fieldset>
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
<%= error_messages_for 'query' %>
|
||||||
|
|
||||||
|
<!--[form:query]-->
|
||||||
|
<div class="box">
|
||||||
|
|
||||||
|
<div class="tabular">
|
||||||
|
<p><label for="query_name">Name</label>
|
||||||
|
<%= text_field 'query', 'name', :size => 80 %></p>
|
||||||
|
|
||||||
|
<p><label for="query_is_public">Public</label>
|
||||||
|
<%= check_box 'query', 'is_public' %></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<%= render :partial => 'filters', :locals => {:query => query}%>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!--[eoform:query]-->
|
||||||
|
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
<h1>Editing query</h1>
|
||||||
|
|
||||||
|
<%= start_form_tag :action => 'edit', :id => @query %>
|
||||||
|
<%= render :partial => 'form', :locals => {:query => @query} %>
|
||||||
|
<%= submit_tag 'Edit' %>
|
||||||
|
<%= end_form_tag %>
|
||||||
|
|
||||||
|
<%= debug @query.statement %>
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
<h1>Listing queries</h1>
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<% for column in Query.content_columns %>
|
||||||
|
<th><%= column.human_name %></th>
|
||||||
|
<% end %>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<% for query in @queries %>
|
||||||
|
<tr>
|
||||||
|
<% for column in Query.content_columns %>
|
||||||
|
<td><%=h query.send(column.name) %></td>
|
||||||
|
<% end %>
|
||||||
|
<td><%= link_to 'Show', :action => 'show', :id => query %></td>
|
||||||
|
<td><%= link_to 'Edit', :action => 'edit', :id => query %></td>
|
||||||
|
<td><%= link_to 'Destroy', { :action => 'destroy', :id => query }, :confirm => 'Are you sure?', :post => true %></td>
|
||||||
|
</tr>
|
||||||
|
<% end %>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<%= link_to 'Previous page', { :page => @query_pages.current.previous } if @query_pages.current.previous %>
|
||||||
|
<%= link_to 'Next page', { :page => @query_pages.current.next } if @query_pages.current.next %>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<%= link_to 'New query', :action => 'new' %>
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
<h1>New query</h1>
|
||||||
|
|
||||||
|
<%= start_form_tag :action => 'new' %>
|
||||||
|
<%= render :partial => 'form', :locals => {:query => @query} %>
|
||||||
|
<%= submit_tag "Create" %>
|
||||||
|
<%= end_form_tag %>
|
||||||
|
|
||||||
|
<%= debug @query %>
|
||||||
|
<%= debug params %>
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
<% for column in Query.content_columns %>
|
||||||
|
<p>
|
||||||
|
<b><%= column.human_name %>:</b> <%=h @query.send(column.name) %>
|
||||||
|
</p>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<%= link_to 'Edit', :action => 'edit', :id => @query %> |
|
||||||
|
<%= link_to 'Back', :action => 'list' %>
|
||||||
@@ -213,7 +213,7 @@ select {
|
|||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
|
||||||
select.select-small
|
.select-small
|
||||||
{
|
{
|
||||||
border: 1px solid #7F9DB9;
|
border: 1px solid #7F9DB9;
|
||||||
padding: 1px;
|
padding: 1px;
|
||||||
|
|||||||
Reference in new issue
Block a user