git-svn-id: http://svn.redmine.org/redmine/trunk@16814 e93f8b46-1217-0410-a6f0-8f06a7374b81tags/4.0.0
@@ -272,6 +272,6 @@ private | |||
end | |||
def retrieve_time_entry_query | |||
retrieve_query(TimeEntryQuery, false) | |||
retrieve_query(TimeEntryQuery, false, :defaults => Setting.time_entry_list_defaults.symbolize_keys) | |||
end | |||
end |
@@ -93,12 +93,13 @@ module QueriesHelper | |||
tags | |||
end | |||
def available_totalable_columns_tags(query) | |||
def available_totalable_columns_tags(query, options={}) | |||
tag_name = (options[:name] || 't') + '[]' | |||
tags = ''.html_safe | |||
query.available_totalable_columns.each do |column| | |||
tags << content_tag('label', check_box_tag('t[]', column.name.to_s, query.totalable_columns.include?(column), :id => nil) + " #{column.caption}", :class => 'inline') | |||
tags << content_tag('label', check_box_tag(tag_name, column.name.to_s, query.totalable_columns.include?(column), :id => nil) + " #{column.caption}", :class => 'inline') | |||
end | |||
tags << hidden_field_tag('t[]', '') | |||
tags << hidden_field_tag(tag_name, '') | |||
tags | |||
end | |||
@@ -282,7 +283,7 @@ module QueriesHelper | |||
end | |||
# Retrieve query from session or build a new query | |||
def retrieve_query(klass=IssueQuery, use_session=true) | |||
def retrieve_query(klass=IssueQuery, use_session=true, options={}) | |||
session_key = klass.name.underscore.to_sym | |||
if params[:query_id].present? | |||
@@ -295,7 +296,7 @@ module QueriesHelper | |||
elsif api_request? || params[:set_filter] || !use_session || session[session_key].nil? || session[session_key][:project_id] != (@project ? @project.id : nil) | |||
# Give it a name, required to be valid | |||
@query = klass.new(:name => "_", :project => @project) | |||
@query.build_from_params(params) | |||
@query.build_from_params(params, options[:defaults]) | |||
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, :sort => @query.sort_criteria.to_a} if use_session | |||
else | |||
# retrieve from session |
@@ -73,7 +73,7 @@ class IssueQuery < Query | |||
options[:draw_progress_line] = (arg == '1' ? '1' : nil) | |||
end | |||
def build_from_params(params) | |||
def build_from_params(params, defaults={}) | |||
super | |||
self.draw_relations = params[:draw_relations] || (params[:query] && params[:query][:draw_relations]) | |||
self.draw_progress_line = params[:draw_progress_line] || (params[:query] && params[:query][:draw_progress_line]) |
@@ -365,7 +365,7 @@ class Query < ActiveRecord::Base | |||
end | |||
# Builds the query from the given params | |||
def build_from_params(params) | |||
def build_from_params(params, defaults={}) | |||
if params[:fields] || params[:f] | |||
self.filters = {} | |||
add_filters(params[:fields] || params[:f], params[:operators] || params[:op], params[:values] || params[:v]) | |||
@@ -374,10 +374,12 @@ class Query < ActiveRecord::Base | |||
add_short_filter(field, params[field]) if params[field] | |||
end | |||
end | |||
self.group_by = params[:group_by] || (params[:query] && params[:query][:group_by]) | |||
self.column_names = params[:c] || (params[:query] && params[:query][:column_names]) | |||
self.totalable_names = params[:t] || (params[:query] && params[:query][:totalable_names]) | |||
self.sort_criteria = params[:sort] || (params[:query] && params[:query][:sort_criteria]) | |||
query_params = params[:query] || defaults || {} | |||
self.group_by = params[:group_by] || query_params[:group_by] | |||
self.column_names = params[:c] || query_params[:column_names] | |||
self.totalable_names = params[:t] || query_params[:totalable_names] | |||
self.sort_criteria = params[:sort] || query_params[:sort_criteria] | |||
self | |||
end | |||
@@ -191,7 +191,7 @@ class TimeEntryQuery < Query | |||
end | |||
# Accepts :from/:to params as shortcut filters | |||
def build_from_params(params) | |||
def build_from_params(params, defaults={}) | |||
super | |||
if params[:from].present? && params[:to].present? | |||
add_filter('spent_on', '><', [params[:from], params[:to]]) |
@@ -6,5 +6,19 @@ | |||
</div> | |||
<fieldset class="box"> | |||
<legend><%= l(:setting_time_entry_list_defaults) %></legend> | |||
<% query = TimeEntryQuery.new(Setting.time_entry_list_defaults) %> | |||
<%= render_query_columns_selection(query, | |||
:name => 'settings[time_entry_list_defaults][column_names]') %> | |||
<p> | |||
<label><%= l(:label_total_plural) %></label> | |||
<%= available_totalable_columns_tags(query, | |||
:name => 'settings[time_entry_list_defaults][totalable_names]') %> | |||
</p> | |||
</fieldset> | |||
<%= submit_tag l(:button_save) %> | |||
<% end %> |
@@ -463,6 +463,7 @@ en: | |||
setting_commit_logs_formatting: Apply text formatting to commit messages | |||
setting_timelog_required_fields: Required fields for time logs | |||
setting_close_duplicate_issues: Close duplicate issues automatically | |||
setting_time_entry_list_defaults: Timelog list defaults | |||
permission_add_project: Create project | |||
permission_add_subprojects: Create subprojects |
@@ -475,6 +475,8 @@ fr: | |||
setting_commit_logs_formatting: Appliquer le formattage de texte aux messages de commit | |||
setting_timelog_required_fields: Champs obligatoire pour les temps passés | |||
setting_close_duplicate_issues: Fermer les doublons automatiquement | |||
setting_time_entry_list_defaults: Affichage par défaut de la liste des temps passés | |||
permission_add_project: Créer un projet | |||
permission_add_subprojects: Créer des sous-projets |
@@ -210,6 +210,16 @@ issue_list_default_totals: | |||
default: [] | |||
display_subprojects_issues: | |||
default: 1 | |||
time_entry_list_defaults: | |||
serialized: true | |||
default: | |||
column_names: | |||
- spent_on | |||
- user | |||
- activity | |||
- issue | |||
- comments | |||
- hours | |||
issue_done_ratio: | |||
default: 'issue_field' | |||
default_projects_public: |
@@ -28,6 +28,11 @@ class TimelogControllerTest < Redmine::ControllerTest | |||
include Redmine::I18n | |||
def setup | |||
super | |||
Setting.default_language = 'en' | |||
end | |||
def test_new | |||
@request.session[:user_id] = 3 | |||
get :new | |||
@@ -705,6 +710,36 @@ class TimelogControllerTest < Redmine::ControllerTest | |||
assert_select '.total-for-hours', :text => 'Hours: 162.90' | |||
assert_select 'form#query_form[action=?]', '/time_entries' | |||
assert_equal ['Date', 'User', 'Activity', 'Issue', 'Comment', 'Hours'], columns_in_list | |||
assert_select '.query-totals>span', 1 | |||
end | |||
def test_index_with_default_query_setting | |||
with_settings :time_entry_list_defaults => {'column_names' => %w(spent_on issue user hours)} do | |||
get :index | |||
assert_response :success | |||
end | |||
assert_equal ['Date', 'Issue', 'User', 'Hours'], columns_in_list | |||
end | |||
def test_index_with_default_query_setting_using_custom_field | |||
field = TimeEntryCustomField.create!(:name => 'Foo', :field_format => 'int') | |||
with_settings :time_entry_list_defaults => { | |||
'column_names' => ["spent_on", "user", "hours", "cf_#{field.id}"], | |||
'totalable_names' => ["hours", "cf_#{field.id}"] | |||
} do | |||
get :index | |||
assert_response :success | |||
end | |||
assert_equal ['Date', 'User', 'Hours', 'Foo'], columns_in_list | |||
assert_select '.total-for-hours' | |||
assert_select ".total-for-cf-#{field.id}" | |||
assert_select '.query-totals>span', 2 | |||
end | |||
def test_index_all_projects_should_show_log_time_link |
@@ -303,11 +303,16 @@ module Redmine | |||
Issue.where(:id => ids).sort_by {|issue| ids.index(issue.id)} | |||
end | |||
# Return the columns that are displayed in the list | |||
# Return the columns that are displayed in the issue list | |||
def columns_in_issues_list | |||
css_select('table.issues thead th:not(.checkbox)').map(&:text) | |||
end | |||
# Return the columns that are displayed in the list | |||
def columns_in_list | |||
css_select('table.list thead th:not(.checkbox)').map(&:text).select(&:present?) | |||
end | |||
# Verifies that the query filters match the expected filters | |||
def assert_query_filters(expected_filters) | |||
response.body =~ /initFilters\(\);\s*((addFilter\(.+\);\s*)*)/ |
@@ -94,11 +94,15 @@ module Redmine | |||
setup do | |||
clear_downloaded_files | |||
Setting.delete_all | |||
Setting.clear_cache | |||
end | |||
teardown do | |||
Capybara.reset_sessions! # Forget the (simulated) browser state | |||
Capybara.use_default_driver # Revert Capybara.current_driver to Capybara.default_driver | |||
Setting.delete_all | |||
Setting.clear_cache | |||
end | |||
end | |||
end |
@@ -1,3 +1,5 @@ | |||
# encoding: utf-8 | |||
# | |||
# Redmine - project management software | |||
# Copyright (C) 2006-2017 Jean-Philippe Lang | |||
# | |||
@@ -69,4 +71,31 @@ class Redmine::UiTest::TimelogTest < Redmine::UiTest::Base | |||
entries = TimeEntry.where(:id => [1,2,3]).to_a | |||
assert entries.all? {|entry| entry.hours == 7.0} | |||
end | |||
def test_default_query_setting | |||
# Display the list with the default settings | |||
visit '/time_entries' | |||
within 'table.time-entries thead' do | |||
assert page.has_no_link?('Tracker') | |||
assert page.has_text?('Comment') | |||
end | |||
# Change the default columns | |||
log_user 'admin', 'admin' | |||
visit '/settings?tab=timelog' | |||
# Remove a column | |||
select 'Comment', :from => 'Selected Columns' | |||
click_on "â†" | |||
# Add a column | |||
select 'Tracker', :from => 'Available Columns' | |||
click_on "→" | |||
click_on 'Save' | |||
# Display the list with updated settings | |||
visit '/time_entries' | |||
within 'table.time-entries thead' do | |||
assert page.has_link?('Tracker') | |||
assert page.has_no_text?('Comment') | |||
end | |||
end | |||
end |