Commit 18f0e9e9 authored by jplang's avatar jplang
Browse files

My page - Spent time: configurable number of days to display (#8761).

git-svn-id: https://svn.redmine.org/redmine/trunk@15942 e93f8b46-1217-0410-a6f0-8f06a7374b81
parent 87040f9d
......@@ -130,6 +130,17 @@ class MyController < ApplicationController
redirect_to my_account_path
end
def update_page
@user = User.current
block_settings = params[:settings] || {}
block_settings.each do |block, settings|
@user.pref.update_block_settings(block, settings)
end
@user.pref.save
@updated_blocks = block_settings.keys
end
# User's page layout configuration
def page_layout
@user = User.current
......
......@@ -45,8 +45,9 @@ module MyHelper
return
end
settings = user.pref.my_page_settings(block)
begin
render(:partial => "my/blocks/#{block}", :locals => {:user => user})
render(:partial => "my/blocks/#{block}", :locals => {:user => user, :settings => settings})
rescue ActionView::MissingTemplate
Rails.logger.warn("Template missing for block \"#{block}\" found in #{user.login} (id=#{user.id}) preferences")
return nil
......@@ -107,13 +108,18 @@ module MyHelper
to_a
end
def timelog_items
TimeEntry.
where("#{TimeEntry.table_name}.user_id = ? AND #{TimeEntry.table_name}.spent_on BETWEEN ? AND ?", User.current.id, User.current.today - 6, User.current.today).
def timelog_items(settings)
days = settings[:days].to_i
days = 7 if days < 1 || days > 365
entries = TimeEntry.
where("#{TimeEntry.table_name}.user_id = ? AND #{TimeEntry.table_name}.spent_on BETWEEN ? AND ?", User.current.id, User.current.today - (days - 1), User.current.today).
joins(:activity, :project).
references(:issue => [:tracker, :status]).
includes(:issue => [:tracker, :status]).
order("#{TimeEntry.table_name}.spent_on DESC, #{Project.table_name}.name ASC, #{Tracker.table_name}.position ASC, #{Issue.table_name}.id ASC").
to_a
return entries, days
end
end
......@@ -91,6 +91,19 @@ class UserPreference < ActiveRecord::Base
self[:my_page_layout] = arg
end
def my_page_settings(block=nil)
s = self[:my_page_settings] ||= {}
if block
s[block] ||= {}
else
s
end
end
def my_page_settings=(arg)
self[:my_page_settings] = arg
end
def remove_block(block)
block = block.to_s.underscore
%w(top left right).each do |f|
......@@ -108,4 +121,9 @@ class UserPreference < ActiveRecord::Base
my_page_layout['top'] ||= []
my_page_layout['top'].unshift(block)
end
def update_block_settings(block, settings)
block_settings = my_page_settings(block).merge(settings.symbolize_keys)
my_page_settings[block] = block_settings
end
end
<%
entries = timelog_items
entries, days = timelog_items(settings)
entries_by_day = entries.group_by(&:spent_on)
%>
<% if User.current.allowed_to?(:log_time, nil, :global => true) %>
<div class="contextual">
<%= link_to l(:button_log_time), new_time_entry_path, :class => "icon icon-add" %>
<%= link_to l(:button_log_time), new_time_entry_path, :class => "icon icon-add" if User.current.allowed_to?(:log_time, nil, :global => true) %>
<%= link_to_function l(:label_options), "$('#timelog-settings').toggle();", :class => 'icon-only icon-settings' %>
</div>
<% end %>
<h3>
<%= link_to l(:label_spent_time), time_entries_path(:user_id => 'me') %>
(<%= l(:label_last_n_days, 7) %>: <%= l_hours_short entries.sum(&:hours) %>)
(<%= l(:label_last_n_days, days) %>: <%= l_hours_short entries.sum(&:hours) %>)
</h3>
<div id="timelog-settings" style="display:none;">
<%= form_tag({}, :remote => true) do %>
<div class="box">
<p>
<label>
<%= l(:button_show) %>:
<%= text_field_tag 'settings[timelog][days]', days, :size => 6 %>
<%= l(:label_day_plural) %>
</label>
</p>
</div>
<p>
<%= submit_tag l(:button_save) %>
<%= link_to_function l(:button_cancel), "$('#timelog-settings').toggle();" %>
</p>
<% end %>
</div>
<% if entries.any? %>
<%= form_tag({}, :data => {:cm_url => time_entries_context_menu_path}) do %>
<table class="list time-entries">
......
<% @updated_blocks.each do |block| %>
$("#block-<%= block %>").html("<%= escape_javascript render_block_content(block.to_s, @user) %>");
<% end %>
......@@ -74,6 +74,7 @@ Rails.application.routes.draw do
match 'my/account', :controller => 'my', :action => 'account', :via => [:get, :post]
match 'my/account/destroy', :controller => 'my', :action => 'destroy', :via => [:get, :post]
match 'my/page', :controller => 'my', :action => 'page', :via => :get
post 'my/page', :to => 'my#update_page'
match 'my', :controller => 'my', :action => 'index', :via => :get # Redirects to my/page
get 'my/api_key', :to => 'my#show_api_key', :as => 'my_api_key'
post 'my/api_key', :to => 'my#reset_api_key'
......
......@@ -1218,6 +1218,7 @@ div.wiki img {vertical-align:middle; max-width:100%;}
.icon-list { background-image: url(../images/text_list_bullets.png); }
.icon-close { background-image: url(../images/close.png); }
.icon-close:hover { background-image: url(../images/close_hl.png); }
.icon-settings { background-image: url(../images/changeset.png); }
.icon-file { background-image: url(../images/files/default.png); }
.icon-file.text-plain { background-image: url(../images/files/text.png); }
......@@ -1242,7 +1243,7 @@ div.wiki img {vertical-align:middle; max-width:100%;}
.sort-handle.ajax-loading { background-image: url(../images/loading.gif); }
tr.ui-sortable-helper { border:1px solid #e4e4e4; }
.contextual>.icon:not(:first-child), .buttons>.icon:not(:first-child) { margin-left: 5px; }
.contextual>*:not(:first-child), .buttons>.icon:not(:first-child) { margin-left: 5px; }
img.gravatar {
vertical-align: middle;
......
......@@ -221,6 +221,18 @@ class MyControllerTest < Redmine::ControllerTest
end
end
def test_update_page_with_blank_preferences
user = User.generate!(:language => 'en')
@request.session[:user_id] = user.id
xhr :post, :update_page, :settings => {'timelog' => {'days' => '14'}}
assert_response :success
assert_include '$("#block-timelog").html(', response.body
assert_include '14 days', response.body
assert_equal({:days => "14"}, user.reload.pref.my_page_settings('timelog'))
end
def test_page_layout
get :page_layout
assert_response :success
......
......@@ -26,6 +26,7 @@ class RoutingMyTest < Redmine::RoutingTest
should_route 'POST /my/account/destroy' => 'my#destroy'
should_route 'GET /my/page' => 'my#page'
should_route 'POST /my/page' => 'my#update_page'
should_route 'GET /my' => 'my#index'
should_route 'GET /my/api_key' => 'my#show_api_key'
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment