summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean-Philippe Lang <jp_lang@yahoo.fr>2007-06-23 13:49:29 +0000
committerJean-Philippe Lang <jp_lang@yahoo.fr>2007-06-23 13:49:29 +0000
commit1c44600c62dc1063583d9e2015ab815d9dd22fa5 (patch)
treedee0938476cc4525b60679905896b7af7a6bd4a7
parent5332c4362cdf7c98a281d88409a07b24767dc2d2 (diff)
downloadredmine-1c44600c62dc1063583d9e2015ab815d9dd22fa5.tar.gz
redmine-1c44600c62dc1063583d9e2015ab815d9dd22fa5.zip
Added per user custom queries.
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
-rw-r--r--app/controllers/projects_controller.rb19
-rw-r--r--app/controllers/queries_controller.rb50
-rw-r--r--app/controllers/reports_controller.rb1
-rw-r--r--app/models/query.rb7
-rw-r--r--app/models/user.rb7
-rw-r--r--app/views/issues/_add_shortcut.rhtml5
-rw-r--r--app/views/layouts/base.rhtml11
-rw-r--r--app/views/projects/add_query.rhtml6
-rw-r--r--app/views/projects/list_issues.rhtml14
-rw-r--r--app/views/projects/show.rhtml3
-rw-r--r--app/views/queries/_filters.rhtml2
-rw-r--r--app/views/queries/_form.rhtml7
-rw-r--r--app/views/queries/edit.rhtml2
-rw-r--r--app/views/queries/index.rhtml29
-rw-r--r--app/views/queries/new.rhtml6
-rw-r--r--app/views/reports/issue_report.rhtml17
-rw-r--r--public/images/save.pngbin591 -> 498 bytes
17 files changed, 112 insertions, 74 deletions
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index 233d012d2..0f9b0f52c 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -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)
diff --git a/app/controllers/queries_controller.rb b/app/controllers/queries_controller.rb
index abafd19d4..631895284 100644
--- a/app/controllers/queries_controller.rb
+++ b/app/controllers/queries_controller.rb
@@ -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
@@ -16,9 +16,35 @@
# 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
diff --git a/app/controllers/reports_controller.rb b/app/controllers/reports_controller.rb
index 59f13d7a5..fdbcc5a53 100644
--- a/app/controllers/reports_controller.rb
+++ b/app/controllers/reports_controller.rb
@@ -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')
diff --git a/app/models/query.rb b/app/models/query.rb
index 081721ca2..b64143674 100644
--- a/app/models/query.rb
+++ b/app/models/query.rb
@@ -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] } },
diff --git a/app/models/user.rb b/app/models/user.rb
index 917745b22..bc5d4ecf8 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -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
index c6a5a4667..000000000
--- a/app/views/issues/_add_shortcut.rhtml
+++ /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 %>
diff --git a/app/views/layouts/base.rhtml b/app/views/layouts/base.rhtml
index 62dd48af2..bcc4026a0 100644
--- a/app/views/layouts/base.rhtml
+++ b/app/views/layouts/base.rhtml
@@ -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" %>
@@ -91,6 +94,14 @@
<%= 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
index 1de027a44..000000000
--- a/app/views/projects/add_query.rhtml
+++ /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
diff --git a/app/views/projects/list_issues.rhtml b/app/views/projects/list_issues.rhtml
index 44ed90019..1cacf0055 100644
--- a/app/views/projects/list_issues.rhtml
+++ b/app/views/projects/list_issues.rhtml
@@ -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')"
@@ -31,12 +31,8 @@
<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 %>
diff --git a/app/views/projects/show.rhtml b/app/views/projects/show.rhtml
index 92668ad71..354568f97 100644
--- a/app/views/projects/show.rhtml
+++ b/app/views/projects/show.rhtml
@@ -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 %>
diff --git a/app/views/queries/_filters.rhtml b/app/views/queries/_filters.rhtml
index af816af95..319349c86 100644
--- a/app/views/queries/_filters.rhtml
+++ b/app/views/queries/_filters.rhtml
@@ -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>
diff --git a/app/views/queries/_form.rhtml b/app/views/queries/_form.rhtml
index d50b1e9b9..9482bd33a 100644
--- a/app/views/queries/_form.rhtml
+++ b/app/views/queries/_form.rhtml
@@ -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
diff --git a/app/views/queries/edit.rhtml b/app/views/queries/edit.rhtml
index 337b498f2..17b19cee9 100644
--- a/app/views/queries/edit.rhtml
+++ b/app/views/queries/edit.rhtml
@@ -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
index 000000000..69cfb8f98
--- /dev/null
+++ b/app/views/queries/index.rhtml
@@ -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
index 000000000..01490a3bd
--- /dev/null
+++ b/app/views/queries/new.rhtml
@@ -0,0 +1,6 @@
+<h2><%= l(:label_query_new) %></h2>
+
+<% form_tag({:action => 'new', :project_id => @query.project}) do %>
+ <%= render :partial => 'form', :locals => {:query => @query} %>
+ <%= submit_tag l(:button_save) %>
+<% end %>
diff --git a/app/views/reports/issue_report.rhtml b/app/views/reports/issue_report.rhtml
index 832bc2cff..3af936a5f 100644
--- a/app/views/reports/issue_report.rhtml
+++ b/app/views/reports/issue_report.rhtml
@@ -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>
diff --git a/public/images/save.png b/public/images/save.png
index 7c499b932..f379d9f34 100644
--- a/public/images/save.png
+++ b/public/images/save.png
Binary files differ