@@ -60,7 +60,7 class QueriesController < ApplicationController | |||||
60 |
|
60 | |||
61 | if @query.save |
|
61 | if @query.save | |
62 | flash[:notice] = l(:notice_successful_create) |
|
62 | flash[:notice] = l(:notice_successful_create) | |
63 |
redirect_to_i |
|
63 | redirect_to_items(:query_id => @query) | |
64 | else |
|
64 | else | |
65 | render :action => 'new', :layout => !request.xhr? |
|
65 | render :action => 'new', :layout => !request.xhr? | |
66 | end |
|
66 | end | |
@@ -74,7 +74,7 class QueriesController < ApplicationController | |||||
74 |
|
74 | |||
75 | if @query.save |
|
75 | if @query.save | |
76 | flash[:notice] = l(:notice_successful_update) |
|
76 | flash[:notice] = l(:notice_successful_update) | |
77 |
redirect_to_i |
|
77 | redirect_to_items(:query_id => @query) | |
78 | else |
|
78 | else | |
79 | render :action => 'edit' |
|
79 | render :action => 'edit' | |
80 | end |
|
80 | end | |
@@ -82,7 +82,7 class QueriesController < ApplicationController | |||||
82 |
|
82 | |||
83 | def destroy |
|
83 | def destroy | |
84 | @query.destroy |
|
84 | @query.destroy | |
85 |
redirect_to_i |
|
85 | redirect_to_items(:set_filter => 1) | |
86 | end |
|
86 | end | |
87 |
|
87 | |||
88 | private |
|
88 | private | |
@@ -117,7 +117,12 class QueriesController < ApplicationController | |||||
117 | @query |
|
117 | @query | |
118 | end |
|
118 | end | |
119 |
|
119 | |||
120 |
def redirect_to_i |
|
120 | def redirect_to_items(options) | |
|
121 | method = "redirect_to_#{@query.class.name.underscore}" | |||
|
122 | send method, options | |||
|
123 | end | |||
|
124 | ||||
|
125 | def redirect_to_issue_query(options) | |||
121 | if params[:gantt] |
|
126 | if params[:gantt] | |
122 | if @project |
|
127 | if @project | |
123 | redirect_to project_gantt_path(@project, options) |
|
128 | redirect_to project_gantt_path(@project, options) | |
@@ -129,6 +134,10 class QueriesController < ApplicationController | |||||
129 | end |
|
134 | end | |
130 | end |
|
135 | end | |
131 |
|
136 | |||
|
137 | def redirect_to_time_entry_query(options) | |||
|
138 | redirect_to _time_entries_path(@project, nil, options) | |||
|
139 | end | |||
|
140 | ||||
132 | # Returns the Query subclass, IssueQuery by default |
|
141 | # Returns the Query subclass, IssueQuery by default | |
133 | # for compatibility with previous behaviour |
|
142 | # for compatibility with previous behaviour | |
134 | def query_class |
|
143 | def query_class |
@@ -40,8 +40,7 class TimelogController < ApplicationController | |||||
40 | include QueriesHelper |
|
40 | include QueriesHelper | |
41 |
|
41 | |||
42 | def index |
|
42 | def index | |
43 | @query = TimeEntryQuery.build_from_params(params, :project => @project, :name => '_') |
|
43 | retrieve_time_entry_query | |
44 |
|
||||
45 | sort_init(@query.sort_criteria.empty? ? [['spent_on', 'desc']] : @query.sort_criteria) |
|
44 | sort_init(@query.sort_criteria.empty? ? [['spent_on', 'desc']] : @query.sort_criteria) | |
46 | sort_update(@query.sortable_columns) |
|
45 | sort_update(@query.sortable_columns) | |
47 | scope = time_entry_scope(:order => sort_clause). |
|
46 | scope = time_entry_scope(:order => sort_clause). | |
@@ -75,7 +74,7 class TimelogController < ApplicationController | |||||
75 | end |
|
74 | end | |
76 |
|
75 | |||
77 | def report |
|
76 | def report | |
78 | @query = TimeEntryQuery.build_from_params(params, :project => @project, :name => '_') |
|
77 | retrieve_time_entry_query | |
79 | scope = time_entry_scope |
|
78 | scope = time_entry_scope | |
80 |
|
79 | |||
81 | @report = Redmine::Helpers::TimeReport.new(@project, @issue, params[:criteria], params[:columns], scope) |
|
80 | @report = Redmine::Helpers::TimeReport.new(@project, @issue, params[:criteria], params[:columns], scope) | |
@@ -271,4 +270,8 private | |||||
271 | end |
|
270 | end | |
272 | scope |
|
271 | scope | |
273 | end |
|
272 | end | |
|
273 | ||||
|
274 | def retrieve_time_entry_query | |||
|
275 | retrieve_query(TimeEntryQuery, false) | |||
|
276 | end | |||
274 | end |
|
277 | end |
@@ -204,26 +204,27 module QueriesHelper | |||||
204 | end |
|
204 | end | |
205 |
|
205 | |||
206 | # Retrieve query from session or build a new query |
|
206 | # Retrieve query from session or build a new query | |
207 | def retrieve_query |
|
207 | def retrieve_query(klass=IssueQuery, use_session=true) | |
208 | if !params[:query_id].blank? |
|
208 | session_key = klass.name.underscore.to_sym | |
|
209 | ||||
|
210 | if params[:query_id].present? | |||
209 | cond = "project_id IS NULL" |
|
211 | cond = "project_id IS NULL" | |
210 | cond << " OR project_id = #{@project.id}" if @project |
|
212 | cond << " OR project_id = #{@project.id}" if @project | |
211 |
@query = |
|
213 | @query = klass.where(cond).find(params[:query_id]) | |
212 | raise ::Unauthorized unless @query.visible? |
|
214 | raise ::Unauthorized unless @query.visible? | |
213 | @query.project = @project |
|
215 | @query.project = @project | |
214 |
session[ |
|
216 | session[session_key] = {:id => @query.id, :project_id => @query.project_id} if use_session | |
215 | sort_clear |
|
217 | sort_clear | |
216 |
elsif api_request? || params[:set_filter] || session[ |
|
218 | elsif api_request? || params[:set_filter] || !use_session || session[session_key].nil? || session[session_key][:project_id] != (@project ? @project.id : nil) | |
217 | # Give it a name, required to be valid |
|
219 | # Give it a name, required to be valid | |
218 |
@query = |
|
220 | @query = klass.new(:name => "_", :project => @project) | |
219 | @query.project = @project |
|
|||
220 | @query.build_from_params(params) |
|
221 | @query.build_from_params(params) | |
221 |
session[ |
|
222 | session[session_key] = {:project_id => @query.project_id, :filters => @query.filters, :group_by => @query.group_by, :column_names => @query.column_names, :totalable_names => @query.totalable_names} if use_session | |
222 | else |
|
223 | else | |
223 | # retrieve from session |
|
224 | # retrieve from session | |
224 | @query = nil |
|
225 | @query = nil | |
225 |
@query = |
|
226 | @query = klass.find_by_id(session[session_key][:id]) if session[session_key][:id] | |
226 |
@query ||= |
|
227 | @query ||= klass.new(:name => "_", :filters => session[session_key][:filters], :group_by => session[session_key][:group_by], :column_names => session[session_key][:column_names], :totalable_names => session[session_key][:totalable_names]) | |
227 | @query.project = @project |
|
228 | @query.project = @project | |
228 | end |
|
229 | end | |
229 | end |
|
230 | end |
@@ -1,6 +1,7 | |||||
1 | <h2><%= l(:label_query_new) %></h2> |
|
1 | <h2><%= l(:label_query_new) %></h2> | |
2 |
|
2 | |||
3 | <%= form_tag(@project ? project_queries_path(@project) : queries_path, :id => "query-form") do %> |
|
3 | <%= form_tag(@project ? project_queries_path(@project) : queries_path, :id => "query-form") do %> | |
|
4 | <%= hidden_field_tag 'type', @query.class.name %> | |||
4 | <%= render :partial => 'form', :locals => {:query => @query} %> |
|
5 | <%= render :partial => 'form', :locals => {:query => @query} %> | |
5 | <%= submit_tag l(:button_save) %> |
|
6 | <%= submit_tag l(:button_save) %> | |
6 | <% end %> |
|
7 | <% end %> |
@@ -1,4 +1,5 | |||||
1 | <div id="query_form_with_buttons" class="hide-when-print"> |
|
1 | <div id="query_form_with_buttons" class="hide-when-print"> | |
|
2 | <%= hidden_field_tag 'set_filter', '1' %> | |||
2 | <div id="query_form_content"> |
|
3 | <div id="query_form_content"> | |
3 | <fieldset id="filters" class="collapsible <%= @query.new_record? ? "" : "collapsed" %>"> |
|
4 | <fieldset id="filters" class="collapsible <%= @query.new_record? ? "" : "collapsed" %>"> | |
4 | <legend onclick="toggleFieldset(this);"><%= l(:label_filter_plural) %></legend> |
|
5 | <legend onclick="toggleFieldset(this);"><%= l(:label_filter_plural) %></legend> | |
@@ -22,11 +23,25 | |||||
22 | <p class="buttons"> |
|
23 | <p class="buttons"> | |
23 | <%= link_to_function l(:button_apply), '$("#query_form").submit()', :class => 'icon icon-checked' %> |
|
24 | <%= link_to_function l(:button_apply), '$("#query_form").submit()', :class => 'icon icon-checked' %> | |
24 | <%= link_to l(:button_clear), {:project_id => @project, :issue_id => @issue}, :class => 'icon icon-reload' %> |
|
25 | <%= link_to l(:button_clear), {:project_id => @project, :issue_id => @issue}, :class => 'icon icon-reload' %> | |
|
26 | <% if @query.new_record? %> | |||
|
27 | <% if User.current.allowed_to?(:save_queries, @project, :global => true) %> | |||
|
28 | <%= link_to_function l(:button_save), | |||
|
29 | "$('#query_form').attr('action', '#{ @project ? new_project_query_path(@project) : new_query_path }').submit()", | |||
|
30 | :class => 'icon icon-save' %> | |||
|
31 | <% end %> | |||
|
32 | <% else %> | |||
|
33 | <% if @query.editable_by?(User.current) %> | |||
|
34 | <%= link_to l(:button_edit), edit_query_path(@query), :class => 'icon icon-edit' %> | |||
|
35 | <%= delete_link query_path(@query) %> | |||
|
36 | <% end %> | |||
|
37 | <% end %> | |||
25 | </p> |
|
38 | </p> | |
|
39 | ||||
|
40 | <%= hidden_field_tag 'type', 'TimeEntryQuery' %> | |||
26 | </div> |
|
41 | </div> | |
27 |
|
42 | |||
28 | <div class="tabs hide-when-print"> |
|
43 | <div class="tabs hide-when-print"> | |
29 | <% query_params = params.slice(:f, :op, :v, :sort) %> |
|
44 | <% query_params = params.slice(:f, :op, :v, :sort, :query_id) %> | |
30 | <ul> |
|
45 | <ul> | |
31 | <li><%= link_to(l(:label_details), _time_entries_path(@project, @issue, query_params), |
|
46 | <li><%= link_to(l(:label_details), _time_entries_path(@project, @issue, query_params), | |
32 | :class => (action_name == 'index' ? 'selected' : nil)) %></li> |
|
47 | :class => (action_name == 'index' ? 'selected' : nil)) %></li> |
@@ -6,7 +6,7 | |||||
6 |
|
6 | |||
7 | <%= render_timelog_breadcrumb %> |
|
7 | <%= render_timelog_breadcrumb %> | |
8 |
|
8 | |||
9 | <h2><%= l(:label_spent_time) %></h2> |
|
9 | <h2><%= @query.new_record? ? l(:label_spent_time) : @query.name %></h2> | |
10 |
|
10 | |||
11 | <%= form_tag(params.slice(:project_id, :issue_id), :method => :get, :id => 'query_form') do %> |
|
11 | <%= form_tag(params.slice(:project_id, :issue_id), :method => :get, :id => 'query_form') do %> | |
12 | <%= render :partial => 'date_range' %> |
|
12 | <%= render :partial => 'date_range' %> | |
@@ -41,7 +41,7 | |||||
41 | </div> |
|
41 | </div> | |
42 | <% end %> |
|
42 | <% end %> | |
43 |
|
43 | |||
44 | <% html_title l(:label_spent_time), l(:label_details) %> |
|
44 | <% html_title(@query.new_record? ? l(:label_spent_time) : @query.name, l(:label_details)) %> | |
45 |
|
45 | |||
46 | <% content_for :header_tags do %> |
|
46 | <% content_for :header_tags do %> | |
47 | <%= auto_discovery_link_tag(:atom, {:issue_id => @issue, :format => 'atom', :key => User.current.rss_key}, :title => l(:label_spent_time)) %> |
|
47 | <%= auto_discovery_link_tag(:atom, {:issue_id => @issue, :format => 'atom', :key => User.current.rss_key}, :title => l(:label_spent_time)) %> |
@@ -6,7 +6,7 | |||||
6 |
|
6 | |||
7 | <%= render_timelog_breadcrumb %> |
|
7 | <%= render_timelog_breadcrumb %> | |
8 |
|
8 | |||
9 | <h2><%= l(:label_spent_time) %></h2> |
|
9 | <h2><%= @query.new_record? ? l(:label_spent_time) : @query.name %></h2> | |
10 |
|
10 | |||
11 | <%= form_tag(params.slice(:project_id, :issue_id), :method => :get, :id => 'query_form') do %> |
|
11 | <%= form_tag(params.slice(:project_id, :issue_id), :method => :get, :id => 'query_form') do %> | |
12 | <% @report.criteria.each do |criterion| %> |
|
12 | <% @report.criteria.each do |criterion| %> | |
@@ -70,5 +70,5 | |||||
70 | <% end %> |
|
70 | <% end %> | |
71 | <% end %> |
|
71 | <% end %> | |
72 |
|
72 | |||
73 | <% html_title l(:label_spent_time), l(:label_report) %> |
|
73 | <% html_title(@query.new_record? ? l(:label_spent_time) : @query.name, l(:label_report)) %> | |
74 |
|
74 |
@@ -806,7 +806,7 module Redmine | |||||
806 | scope = object.project.shared_versions |
|
806 | scope = object.project.shared_versions | |
807 | filtered_versions_options(custom_field, scope, all_statuses) |
|
807 | filtered_versions_options(custom_field, scope, all_statuses) | |
808 | elsif object.nil? |
|
808 | elsif object.nil? | |
809 | scope = Version.visible.where(:sharing => 'system') |
|
809 | scope = ::Version.visible.where(:sharing => 'system') | |
810 | filtered_versions_options(custom_field, scope, all_statuses) |
|
810 | filtered_versions_options(custom_field, scope, all_statuses) | |
811 | else |
|
811 | else | |
812 | [] |
|
812 | [] |
@@ -399,9 +399,9 class IssuesControllerTest < ActionController::TestCase | |||||
399 | def test_index_with_query_id_and_project_id_should_set_session_query |
|
399 | def test_index_with_query_id_and_project_id_should_set_session_query | |
400 | get :index, :project_id => 1, :query_id => 4 |
|
400 | get :index, :project_id => 1, :query_id => 4 | |
401 | assert_response :success |
|
401 | assert_response :success | |
402 | assert_kind_of Hash, session[:query] |
|
402 | assert_kind_of Hash, session[:issue_query] | |
403 | assert_equal 4, session[:query][:id] |
|
403 | assert_equal 4, session[:issue_query][:id] | |
404 | assert_equal 1, session[:query][:project_id] |
|
404 | assert_equal 1, session[:issue_query][:project_id] | |
405 | end |
|
405 | end | |
406 |
|
406 | |||
407 | def test_index_with_invalid_query_id_should_respond_404 |
|
407 | def test_index_with_invalid_query_id_should_respond_404 | |
@@ -411,7 +411,7 class IssuesControllerTest < ActionController::TestCase | |||||
411 |
|
411 | |||
412 | def test_index_with_cross_project_query_in_session_should_show_project_issues |
|
412 | def test_index_with_cross_project_query_in_session_should_show_project_issues | |
413 | q = IssueQuery.create!(:name => "test", :user_id => 2, :visibility => IssueQuery::VISIBILITY_PRIVATE, :project => nil) |
|
413 | q = IssueQuery.create!(:name => "test", :user_id => 2, :visibility => IssueQuery::VISIBILITY_PRIVATE, :project => nil) | |
414 | @request.session[:query] = {:id => q.id, :project_id => 1} |
|
414 | @request.session[:issue_query] = {:id => q.id, :project_id => 1} | |
415 |
|
415 | |||
416 | with_settings :display_subprojects_issues => '0' do |
|
416 | with_settings :display_subprojects_issues => '0' do | |
417 | get :index, :project_id => 1 |
|
417 | get :index, :project_id => 1 | |
@@ -832,9 +832,9 class IssuesControllerTest < ActionController::TestCase | |||||
832 | assert_equal columns, query.column_names.map(&:to_s) |
|
832 | assert_equal columns, query.column_names.map(&:to_s) | |
833 |
|
833 | |||
834 | # columns should be stored in session |
|
834 | # columns should be stored in session | |
835 | assert_kind_of Hash, session[:query] |
|
835 | assert_kind_of Hash, session[:issue_query] | |
836 | assert_kind_of Array, session[:query][:column_names] |
|
836 | assert_kind_of Array, session[:issue_query][:column_names] | |
837 | assert_equal columns, session[:query][:column_names].map(&:to_s) |
|
837 | assert_equal columns, session[:issue_query][:column_names].map(&:to_s) | |
838 |
|
838 | |||
839 | # ensure only these columns are kept in the selected columns list |
|
839 | # ensure only these columns are kept in the selected columns list | |
840 | assert_select 'select#selected_columns option' do |
|
840 | assert_select 'select#selected_columns option' do |
@@ -58,6 +58,13 class QueriesControllerTest < ActionController::TestCase | |||||
58 | assert_response 404 |
|
58 | assert_response 404 | |
59 | end |
|
59 | end | |
60 |
|
60 | |||
|
61 | def test_new_time_entry_query | |||
|
62 | @request.session[:user_id] = 2 | |||
|
63 | get :new, :project_id => 1, :type => 'TimeEntryQuery' | |||
|
64 | assert_response :success | |||
|
65 | assert_select 'input[name=type][value=?]', 'TimeEntryQuery' | |||
|
66 | end | |||
|
67 | ||||
61 | def test_create_project_public_query |
|
68 | def test_create_project_public_query | |
62 | @request.session[:user_id] = 2 |
|
69 | @request.session[:user_id] = 2 | |
63 | post :create, |
|
70 | post :create, | |
@@ -263,6 +270,26 class QueriesControllerTest < ActionController::TestCase | |||||
263 | assert_equal Query::VISIBILITY_PUBLIC, query.visibility |
|
270 | assert_equal Query::VISIBILITY_PUBLIC, query.visibility | |
264 | end |
|
271 | end | |
265 |
|
272 | |||
|
273 | def test_create_project_public_time_entry_query | |||
|
274 | @request.session[:user_id] = 2 | |||
|
275 | ||||
|
276 | q = new_record(TimeEntryQuery) do | |||
|
277 | post :create, | |||
|
278 | :project_id => 'ecookbook', | |||
|
279 | :type => 'TimeEntryQuery', | |||
|
280 | :default_columns => '1', | |||
|
281 | :f => ["spent_on"], | |||
|
282 | :op => {"spent_on" => "="}, | |||
|
283 | :v => { "spent_on" => ["2016-07-14"]}, | |||
|
284 | :query => {"name" => "test_new_project_public_query", "visibility" => "2"} | |||
|
285 | end | |||
|
286 | ||||
|
287 | assert_redirected_to :controller => 'timelog', :action => 'index', :project_id => 'ecookbook', :query_id => q.id | |||
|
288 | assert q.is_public? | |||
|
289 | assert q.has_default_columns? | |||
|
290 | assert q.valid? | |||
|
291 | end | |||
|
292 | ||||
266 | def test_edit_global_public_query |
|
293 | def test_edit_global_public_query | |
267 | @request.session[:user_id] = 1 |
|
294 | @request.session[:user_id] = 1 | |
268 | get :edit, :id => 4 |
|
295 | get :edit, :id => 4 |
@@ -759,6 +759,16 class TimelogControllerTest < ActionController::TestCase | |||||
759 | assert_equal values.sort, values |
|
759 | assert_equal values.sort, values | |
760 | end |
|
760 | end | |
761 |
|
761 | |||
|
762 | def test_index_with_query | |||
|
763 | query = TimeEntryQuery.new(:project_id => 1, :name => 'Time Entry Query', :visibility => 2) | |||
|
764 | query.save! | |||
|
765 | @request.session[:user_id] = 2 | |||
|
766 | ||||
|
767 | get :index, :project_id => 'ecookbook', :query_id => query.id | |||
|
768 | assert_response :success | |||
|
769 | assert_select 'h2', :text => query.name | |||
|
770 | end | |||
|
771 | ||||
762 | def test_index_atom_feed |
|
772 | def test_index_atom_feed | |
763 | get :index, :project_id => 1, :format => 'atom' |
|
773 | get :index, :project_id => 1, :format => 'atom' | |
764 | assert_response :success |
|
774 | assert_response :success |
General Comments 0
You need to be logged in to leave comments.
Login now