]> source.dussan.org Git - redmine.git/commitdiff
Added per user custom queries.
authorJean-Philippe Lang <jp_lang@yahoo.fr>
Sat, 23 Jun 2007 13:49:29 +0000 (13:49 +0000)
committerJean-Philippe Lang <jp_lang@yahoo.fr>
Sat, 23 Jun 2007 13:49:29 +0000 (13:49 +0000)
Any logged in user can now save queries (they are not visible to the other users).
Only users with explicit permission can manage queries that are visible to anyone.
The queries list is removed from the "Reports" view. It can now be accessed from the issues list.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@566 e93f8b46-1217-0410-a6f0-8f06a7374b81

17 files changed:
app/controllers/projects_controller.rb
app/controllers/queries_controller.rb
app/controllers/reports_controller.rb
app/models/query.rb
app/models/user.rb
app/views/issues/_add_shortcut.rhtml [deleted file]
app/views/layouts/base.rhtml
app/views/projects/add_query.rhtml [deleted file]
app/views/projects/list_issues.rhtml
app/views/projects/show.rhtml
app/views/queries/_filters.rhtml
app/views/queries/_form.rhtml
app/views/queries/edit.rhtml
app/views/queries/index.rhtml [new file with mode: 0644]
app/views/queries/new.rhtml [new file with mode: 0644]
app/views/reports/issue_report.rhtml
public/images/save.png

index 233d012d2aa02f1463c889b7e9bed1d0a2b282c2..0f9b0f52c5a8e3be59359e0b92c534b318284ee9 100644 (file)
@@ -288,8 +288,7 @@ class ProjectsController < ApplicationController
                                                :conditions => @query.statement,
                                                :limit  =>  @issue_pages.items_per_page,
                                                :offset =>  @issue_pages.current.offset                                         
-    end    
-    @trackers = Tracker.find :all, :order => 'position'
+    end
     render :layout => false if request.xhr?
   end
 
@@ -400,22 +399,6 @@ class ProjectsController < ApplicationController
     end
   end
 
-  def add_query
-    @query = Query.new(params[:query])
-    @query.project = @project
-    @query.user = logged_in_user
-    
-    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] = l(:notice_successful_create)
-      redirect_to :controller => 'reports', :action => 'issue_report', :id => @project
-    end    
-    render :layout => false if request.xhr?
-  end
-
   # Add a news to @project
   def add_news
     @news = News.new(:project => @project)
index abafd19d47ad29f30d159efe718273936a883c68..6318952842e056859d92ab01a2fec18d74d3f8ab 100644 (file)
@@ -1,5 +1,5 @@
 # redMine - project management software
-# Copyright (C) 2006  Jean-Philippe Lang
+# Copyright (C) 2006-2007  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
 class QueriesController < ApplicationController
-  layout 'base'
-  before_filter :require_login, :find_query
+  layout 'base'  
+  before_filter :require_login, :except => :index
+  before_filter :find_project, :check_project_privacy
 
+  def index
+    @queries = @project.queries.find(:all, 
+                                     :order => "name ASC",
+                                     :conditions => ["is_public = ? or user_id = ?", true, (logged_in_user ? logged_in_user.id : 0)])
+  end
+  
+  def new
+    @query = Query.new(params[:query])
+    @query.project = @project
+    @query.user = logged_in_user
+    @query.executed_by = logged_in_user
+    @query.is_public = false unless logged_in_user.authorized_to(@project, 'projects/add_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] = l(:notice_successful_create)
+      redirect_to :controller => 'projects', :action => 'list_issues', :id => @project, :query_id => @query
+      return
+    end
+    render :layout => false if request.xhr?
+  end
+  
   def edit
     if request.post?
       @query.filters = {}
@@ -26,6 +52,7 @@ class QueriesController < ApplicationController
         @query.add_filter(field, params[:operators][field], params[:values][field])
       end if params[:fields]
       @query.attributes = params[:query]
+      @query.is_public = false unless logged_in_user.authorized_to(@project, 'projects/add_query')
           
       if @query.save
         flash[:notice] = l(:notice_successful_update)
@@ -36,16 +63,19 @@ class QueriesController < ApplicationController
 
   def destroy
     @query.destroy if request.post?
-    redirect_to :controller => 'reports', :action => 'issue_report', :id => @project
+    redirect_to :controller => 'queries', :project_id => @project
   end
   
 private
-  def find_query
-    @query = Query.find(params[:id])
-    @query.executed_by = logged_in_user
-    @project = @query.project
-    # check if user is allowed to manage queries (same permission as add_query)
-    authorize('projects', 'add_query')
+  def find_project
+    if params[:id]
+      @query = Query.find(params[:id])
+      @query.executed_by = logged_in_user
+      @project = @query.project
+      render_403 unless @query.editable_by?(logged_in_user)
+    else
+      @project = Project.find(params[:project_id])
+    end
   rescue ActiveRecord::RecordNotFound
     render_404
   end
index 59f13d7a53f8dcb360a31f4f670bb34dc92b5b2f..fdbcc5a53969fc45fad3acf786a27c6e84bc0f01 100644 (file)
@@ -60,7 +60,6 @@ class ReportsController < ApplicationController
       @report_title = l(:field_subproject)
       render :template => "reports/issue_report_details"  
     else
-      @queries = @project.queries.find :all, :conditions => ["is_public=? or user_id=?", true, (logged_in_user ? logged_in_user.id : 0)]
       @trackers = Tracker.find(:all, :order => 'position')
       @versions = @project.versions.sort
       @priorities = Enumeration::get_values('IPRI')
index 081721ca233c7fcb6dff46eb634b5001635444e8..b6414367484bde728e063606ed5e9b3b60cf1c92 100644 (file)
@@ -57,7 +57,6 @@ class Query < ActiveRecord::Base
   def initialize(attributes = nil)
     super attributes
     self.filters ||= { 'status_id' => {:operator => "o", :values => [""]} }
-    self.is_public = true
   end
   
   def executed_by=(user)
@@ -75,6 +74,12 @@ class Query < ActiveRecord::Base
     end if filters
   end
   
+  def editable_by?(user)
+    return false unless user
+    return true if !is_public && self.user_id == user.id
+    is_public && user.authorized_to(project, "projects/add_query")
+  end
+  
   def available_filters
     return @available_filters if @available_filters
     @available_filters = { "status_id" => { :type => :list_status, :order => 1, :values => IssueStatus.find(:all, :order => 'position').collect{|s| [s.name, s.id.to_s] } },       
index 917745b224fedc3e0912a7ad6b4283645e729d27..bc5d4ecf863d8baf15f77a6982113cc4dafaa0cf 100644 (file)
@@ -125,10 +125,17 @@ class User < ActiveRecord::Base
   end
   
   def role_for_project(project)
+    return nil unless project
     member = memberships.detect {|m| m.project_id == project.id}
     member ? member.role : nil 
   end
   
+  def authorized_to(project, action)
+    return true if self.admin?
+    role = role_for_project(project)
+    role && Permission.allowed_to_role(action, role)
+  end
+  
   def pref
     self.preference ||= UserPreference.new(:user => self)
   end
diff --git a/app/views/issues/_add_shortcut.rhtml b/app/views/issues/_add_shortcut.rhtml
deleted file mode 100644 (file)
index c6a5a46..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-<% if authorize_for('projects', 'add_issue') %>
-<% form_tag({ :controller => 'projects', :action => 'add_issue', :id => @project }, :method => 'get') do %>
-<%= l(:label_issue_new) %>: <%= select_tag 'tracker_id', ("<option></option>" + options_from_collection_for_select(trackers, 'id', 'name')), :onchange => "if (this.value!='') {this.form.submit();}" %>
-<% end %>
-<% end %>
index 62dd48af20e06ecc1fd6ab3873564a411aca2f89..bcc4026a00e5b518752c62f8a6e2fc7ba20d2b83 100644 (file)
@@ -77,6 +77,9 @@
         <%= link_to l(:label_calendar), {:controller => 'projects', :action => 'calendar', :id => @project }, :class => "menuItem" %>
         <%= link_to l(:label_gantt), {:controller => 'projects', :action => 'gantt', :id => @project }, :class => "menuItem" %>
         <%= link_to l(:label_issue_plural), {:controller => 'projects', :action => 'list_issues', :id => @project }, :class => "menuItem" %>
+        <% if @project && authorize_for('projects', 'add_issue') %>
+          <a class="menuItem" href="#" onmouseover="menuItemMouseover(event,'menuNewIssue');" onclick="this.blur(); return false;"><span class="menuItemText"><%= l(:label_issue_new) %></span><span class="menuItemArrow">&#9654;</span></a>
+        <% end %>
         <%= link_to l(:label_report_plural), {:controller => 'reports', :action => 'issue_report', :id => @project }, :class => "menuItem" %>
         <%= link_to l(:label_activity), {:controller => 'projects', :action => 'activity', :id => @project }, :class => "menuItem" %>
         <%= link_to l(:label_news_plural), {:controller => 'projects', :action => 'list_news', :id => @project }, :class => "menuItem" %>
         <%= link_to_if_authorized l(:label_settings), {:controller => 'projects', :action => 'settings', :id => @project }, :class => "menuItem" %>
     </div>
     <% end %>
+    
+    <% if @project && authorize_for('projects', 'add_issue') %>
+        <div id="menuNewIssue" class="menu" onmouseover="menuMouseover(event)">
+        <% Tracker.find(:all, :order => 'position').each do |tracker| %>
+            <%= link_to tracker.name, {:controller => 'projects', :action => 'add_issue', :id => @project, :tracker_id => tracker}, :class => "menuItem" %>
+        <% end %>
+        </div>
+    <% end %>
 
     <% if loggedin? and @logged_in_user.memberships.any? %>
         <div id="menuAllProjects" class="menu" onmouseover="menuMouseover(event)">
diff --git a/app/views/projects/add_query.rhtml b/app/views/projects/add_query.rhtml
deleted file mode 100644 (file)
index 1de027a..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-<h2><%= l(:label_query_new) %></h2>
-
-<% form_tag({:action => 'add_query', :id => @project}) do %>
-  <%= render :partial => 'queries/form', :locals => {:query => @query} %>
-  <%= submit_tag l(:button_create) %>
-<% end %>
\ No newline at end of file
index 44ed900196dc5009d3f89f59ad9acc0bb8971753..1cacf0055666e6fe6fcd0981b6a923b2f31141b8 100644 (file)
@@ -1,6 +1,6 @@
 <% if @query.new_record? %>
     <div class="contextual">
-    <%= render :partial => 'issues/add_shortcut', :locals => {:trackers => @trackers } %>
+      <%= link_to l(:label_query_plural), :controller => 'queries', :project_id => @project %>
     </div>
     <h2><%=l(:label_issue_plural)%></h2>
     
@@ -19,9 +19,9 @@
                          :update => "content",
                        }, :class => 'icon icon-reload'  %>
                        
-    <% if authorize_for('projects', 'add_query') %>    
+    <% if loggedin? %>    
     <%= link_to_remote l(:button_save), 
-                       { :url => { :controller => 'projects', :action => "add_query", :id => @project },
+                       { :url => { :controller => 'queries', :action => 'new', :project_id => @project },
                          :method => 'get',
                          :update => "content",
                          :with => "Form.serialize('query_form')"
     <br />
 <% else %>
     <div class="contextual">
-        <%= render :partial => 'issues/add_shortcut', :locals => {:trackers => @trackers } %>
-        <%= link_to l(:button_clear), {:controller => 'projects', :action => 'list_issues', :id => @project, :set_filter => 1}, :class => 'icon icon-reload' %>
-        <% if authorize_for('projects', 'add_query') %>
-            <%= link_to l(:button_edit), {:controller => 'queries', :action => 'edit', :id => @query}, :class => 'icon icon-edit' %>
-            <%= link_to l(:button_delete), {:controller => 'queries', :action => 'destroy', :id => @query}, :confirm => l(:text_are_you_sure), :method => :post, :class => 'icon icon-del' %>
-        <% end %>        
+        <%= link_to l(:label_query_plural), {:controller => 'queries', :project_id => @project} %> |
+        <%= link_to l(:label_issue_view_all), {:controller => 'projects', :action => 'list_issues', :id => @project, :set_filter => 1} %>
     </div>    
     <h2><%= @query.name %></h2>
 <% end %>
index 92668ad7123d1ed3c50719495b3f4efcc182f9f6..354568f97aa5ce079b104632e3e87086c9788116 100644 (file)
@@ -20,9 +20,6 @@
        </ul>   
 
   <div class="box">
-    <div class="contextual">
-    <%= render :partial => 'issues/add_shortcut', :locals => {:trackers => @trackers } %>
-    </div>
     <h3 class="icon22 icon22-tracker"><%=l(:label_issue_tracking)%></h3>
     <ul>
     <% for tracker in @trackers %>    
index af816af95abd0596543494ced034b6686cb03649..319349c86206f91f6f0ab21198157190cbdb97d4 100644 (file)
@@ -55,7 +55,7 @@ function toggle_multi_select(field) {
 //]]>
 </script>
 
-<fieldset style="margin:0;"><legend><%= l(:label_filter_plural) %></legend>
+<fieldset><legend><%= l(:label_filter_plural) %></legend>
 <table width="100%">
 <tr>
 <td>
index d50b1e9b9cf3ee2ed7d3b28bbd27f8a2dc964fcb..9482bd33a7f56fccd20a3955a4f803d68373cd6d 100644 (file)
@@ -1,12 +1,15 @@
 <%= error_messages_for 'query' %>
 
-<!--[form:query]-->
 <div class="box">
 <div class="tabular">
 <p><label for="query_name"><%=l(:field_name)%></label>
 <%= text_field 'query', 'name', :size => 80 %></p>
+
+<% if authorize_for('projects', 'add_query') %>
+  <p><label for="query_is_public"><%=l(:field_is_public)%></label>
+  <%= check_box 'query', 'is_public' %></p>
+<% end %>
 </div>
 
 <%= render :partial => 'queries/filters', :locals => {:query => query}%>
 </div>
-<!--[eoform:query]-->
\ No newline at end of file
index 337b498f263d218b0c56d2728641e60ec104f639..17b19cee94ad836da4eb6fbb27586ab510227128 100644 (file)
@@ -3,4 +3,4 @@
 <% form_tag({:action => 'edit', :id => @query}) do %>
   <%= render :partial => 'form', :locals => {:query => @query} %>
   <%= submit_tag l(:button_save) %>
-<% end %>
\ No newline at end of file
+<% end %>
diff --git a/app/views/queries/index.rhtml b/app/views/queries/index.rhtml
new file mode 100644 (file)
index 0000000..69cfb8f
--- /dev/null
@@ -0,0 +1,29 @@
+<div class="contextual">
+<% if loggedin? %>
+<%= link_to l(:label_query_new), {:controller => 'queries', :action => 'new', :project_id => @project}, :class => 'icon icon-add' %>
+<% end %>
+</div>
+
+<h2><%= l(:label_query_plural) %></h2>
+
+<% if @queries.empty? %>
+  <p><i><%=l(:label_no_data)%></i></p>
+<% else %>
+  <table class="list">
+  <% @queries.each do |query| %>
+    <tr class="<%= cycle('odd', 'even') %>">
+      <td>
+        <%= link_to query.name, :controller => 'projects', :action => 'list_issues', :id => @project, :query_id => query %>
+      </td>
+      <td align="right">
+        <small>
+        <% if query.editable_by?(@logged_in_user) %>    
+        <%= link_to l(:button_edit), {:controller => 'queries', :action => 'edit', :id => query}, :class => 'icon icon-edit' %>
+        <%= link_to l(:button_delete), {:controller => 'queries', :action => 'destroy', :id => query}, :confirm => l(:text_are_you_sure), :method => :post, :class => 'icon icon-del' %>
+        </small>
+      <% end %>
+      </td>
+    </tr>
+  <% end %>
+  </table>
+<% end %>
diff --git a/app/views/queries/new.rhtml b/app/views/queries/new.rhtml
new file mode 100644 (file)
index 0000000..01490a3
--- /dev/null
@@ -0,0 +1,6 @@
+<h2><%= l(:label_query_new) %></h2>\r
+\r
+<% form_tag({:action => 'new', :project_id => @query.project}) do %>\r
+  <%= render :partial => 'form', :locals => {:query => @query} %>\r
+  <%= submit_tag l(:button_save) %>\r
+<% end %>\r
index 832bc2cff5ea5acb2695a68a47b6cdea4786340a..3af936a5f525e5809f1e170c89dcf4c801681317 100644 (file)
@@ -1,27 +1,10 @@
 <h2><%=l(:label_report_plural)%></h2>
 
-<div class="splitcontentleft">
-<div class="contextual">
-<%= link_to_if_authorized l(:label_query_new), {:controller => 'projects', :action => 'add_query', :id => @project}, :class => 'icon icon-add' %>
-</div>
-<h3><%= l(:label_query_plural) %></h3>
-
-<% if @queries.empty? %><p><i><%=l(:label_no_data)%></i></p><% end %>
-<ul>
-<% @queries.each do |query| %>
-    <li><%= link_to query.name, :controller => 'projects', :action => 'list_issues', :id => @project, :query_id => query %></li>
-<% end %>
-</ul>
-</div>
-<div class="splitcontentright">
 <% if @total_hours %>
 <h3 class="textright"><%= l(:label_spent_time) %>:
 <%= link_to(lwr(:label_f_hour, @total_hours), {:controller => 'timelog', :action => 'details', :project_id => @project}, :class => 'icon icon-time') %>
 </h3>
 <% end %>
-</div>
-
-<div class="clear"></div>
 
 <div class="splitcontentleft">
 <h3><%=l(:field_tracker)%>&nbsp;&nbsp;<%= link_to image_tag('zoom_in.png'), :detail => 'tracker' %></h3>
index 7c499b932551f6221a3deb184fc242b6089818ff..f379d9f34f5791339f2214ba27c2baa59cb1b642 100644 (file)
Binary files a/public/images/save.png and b/public/images/save.png differ