@@ -0,0 +1,3 | |||
|
1 | <% @updated_blocks.each do |block| %> | |
|
2 | $("#block-<%= block %>").html("<%= escape_javascript render_block_content(block.to_s, @user) %>"); | |
|
3 | <% end %> |
@@ -130,6 +130,17 class MyController < ApplicationController | |||
|
130 | 130 | redirect_to my_account_path |
|
131 | 131 | end |
|
132 | 132 | |
|
133 | def update_page | |
|
134 | @user = User.current | |
|
135 | block_settings = params[:settings] || {} | |
|
136 | ||
|
137 | block_settings.each do |block, settings| | |
|
138 | @user.pref.update_block_settings(block, settings) | |
|
139 | end | |
|
140 | @user.pref.save | |
|
141 | @updated_blocks = block_settings.keys | |
|
142 | end | |
|
143 | ||
|
133 | 144 | # User's page layout configuration |
|
134 | 145 | def page_layout |
|
135 | 146 | @user = User.current |
@@ -45,8 +45,9 module MyHelper | |||
|
45 | 45 | return |
|
46 | 46 | end |
|
47 | 47 | |
|
48 | settings = user.pref.my_page_settings(block) | |
|
48 | 49 | begin |
|
49 | render(:partial => "my/blocks/#{block}", :locals => {:user => user}) | |
|
50 | render(:partial => "my/blocks/#{block}", :locals => {:user => user, :settings => settings}) | |
|
50 | 51 | rescue ActionView::MissingTemplate |
|
51 | 52 | Rails.logger.warn("Template missing for block \"#{block}\" found in #{user.login} (id=#{user.id}) preferences") |
|
52 | 53 | return nil |
@@ -107,13 +108,18 module MyHelper | |||
|
107 | 108 | to_a |
|
108 | 109 | end |
|
109 | 110 | |
|
110 | def timelog_items | |
|
111 | TimeEntry. | |
|
112 | where("#{TimeEntry.table_name}.user_id = ? AND #{TimeEntry.table_name}.spent_on BETWEEN ? AND ?", User.current.id, User.current.today - 6, User.current.today). | |
|
111 | def timelog_items(settings) | |
|
112 | days = settings[:days].to_i | |
|
113 | days = 7 if days < 1 || days > 365 | |
|
114 | ||
|
115 | entries = TimeEntry. | |
|
116 | 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). | |
|
113 | 117 | joins(:activity, :project). |
|
114 | 118 | references(:issue => [:tracker, :status]). |
|
115 | 119 | includes(:issue => [:tracker, :status]). |
|
116 | 120 | order("#{TimeEntry.table_name}.spent_on DESC, #{Project.table_name}.name ASC, #{Tracker.table_name}.position ASC, #{Issue.table_name}.id ASC"). |
|
117 | 121 | to_a |
|
122 | ||
|
123 | return entries, days | |
|
118 | 124 | end |
|
119 | 125 | end |
@@ -91,6 +91,19 class UserPreference < ActiveRecord::Base | |||
|
91 | 91 | self[:my_page_layout] = arg |
|
92 | 92 | end |
|
93 | 93 | |
|
94 | def my_page_settings(block=nil) | |
|
95 | s = self[:my_page_settings] ||= {} | |
|
96 | if block | |
|
97 | s[block] ||= {} | |
|
98 | else | |
|
99 | s | |
|
100 | end | |
|
101 | end | |
|
102 | ||
|
103 | def my_page_settings=(arg) | |
|
104 | self[:my_page_settings] = arg | |
|
105 | end | |
|
106 | ||
|
94 | 107 | def remove_block(block) |
|
95 | 108 | block = block.to_s.underscore |
|
96 | 109 | %w(top left right).each do |f| |
@@ -108,4 +121,9 class UserPreference < ActiveRecord::Base | |||
|
108 | 121 | my_page_layout['top'] ||= [] |
|
109 | 122 | my_page_layout['top'].unshift(block) |
|
110 | 123 | end |
|
124 | ||
|
125 | def update_block_settings(block, settings) | |
|
126 | block_settings = my_page_settings(block).merge(settings.symbolize_keys) | |
|
127 | my_page_settings[block] = block_settings | |
|
128 | end | |
|
111 | 129 | end |
@@ -1,18 +1,37 | |||
|
1 | 1 | <% |
|
2 | entries = timelog_items | |
|
2 | entries, days = timelog_items(settings) | |
|
3 | 3 | entries_by_day = entries.group_by(&:spent_on) |
|
4 | 4 | %> |
|
5 | <% if User.current.allowed_to?(:log_time, nil, :global => true) %> | |
|
5 | ||
|
6 | 6 | <div class="contextual"> |
|
7 | <%= link_to l(:button_log_time), new_time_entry_path, :class => "icon icon-add" %> | |
|
7 | <%= link_to l(:button_log_time), new_time_entry_path, :class => "icon icon-add" if User.current.allowed_to?(:log_time, nil, :global => true) %> | |
|
8 | <%= link_to_function l(:label_options), "$('#timelog-settings').toggle();", :class => 'icon-only icon-settings' %> | |
|
8 | 9 | </div> |
|
9 | <% end %> | |
|
10 | 10 | |
|
11 | 11 | <h3> |
|
12 | 12 | <%= link_to l(:label_spent_time), time_entries_path(:user_id => 'me') %> |
|
13 |
(<%= l(:label_last_n_days, |
|
|
13 | (<%= l(:label_last_n_days, days) %>: <%= l_hours_short entries.sum(&:hours) %>) | |
|
14 | 14 | </h3> |
|
15 | 15 | |
|
16 | ||
|
17 | <div id="timelog-settings" style="display:none;"> | |
|
18 | <%= form_tag({}, :remote => true) do %> | |
|
19 | <div class="box"> | |
|
20 | <p> | |
|
21 | <label> | |
|
22 | <%= l(:button_show) %>: | |
|
23 | <%= text_field_tag 'settings[timelog][days]', days, :size => 6 %> | |
|
24 | <%= l(:label_day_plural) %> | |
|
25 | </label> | |
|
26 | </p> | |
|
27 | </div> | |
|
28 | <p> | |
|
29 | <%= submit_tag l(:button_save) %> | |
|
30 | <%= link_to_function l(:button_cancel), "$('#timelog-settings').toggle();" %> | |
|
31 | </p> | |
|
32 | <% end %> | |
|
33 | </div> | |
|
34 | ||
|
16 | 35 | <% if entries.any? %> |
|
17 | 36 | <%= form_tag({}, :data => {:cm_url => time_entries_context_menu_path}) do %> |
|
18 | 37 | <table class="list time-entries"> |
@@ -74,6 +74,7 Rails.application.routes.draw do | |||
|
74 | 74 | match 'my/account', :controller => 'my', :action => 'account', :via => [:get, :post] |
|
75 | 75 | match 'my/account/destroy', :controller => 'my', :action => 'destroy', :via => [:get, :post] |
|
76 | 76 | match 'my/page', :controller => 'my', :action => 'page', :via => :get |
|
77 | post 'my/page', :to => 'my#update_page' | |
|
77 | 78 | match 'my', :controller => 'my', :action => 'index', :via => :get # Redirects to my/page |
|
78 | 79 | get 'my/api_key', :to => 'my#show_api_key', :as => 'my_api_key' |
|
79 | 80 | post 'my/api_key', :to => 'my#reset_api_key' |
@@ -1218,6 +1218,7 div.wiki img {vertical-align:middle; max-width:100%;} | |||
|
1218 | 1218 | .icon-list { background-image: url(../images/text_list_bullets.png); } |
|
1219 | 1219 | .icon-close { background-image: url(../images/close.png); } |
|
1220 | 1220 | .icon-close:hover { background-image: url(../images/close_hl.png); } |
|
1221 | .icon-settings { background-image: url(../images/changeset.png); } | |
|
1221 | 1222 | |
|
1222 | 1223 | .icon-file { background-image: url(../images/files/default.png); } |
|
1223 | 1224 | .icon-file.text-plain { background-image: url(../images/files/text.png); } |
@@ -1242,7 +1243,7 div.wiki img {vertical-align:middle; max-width:100%;} | |||
|
1242 | 1243 | .sort-handle.ajax-loading { background-image: url(../images/loading.gif); } |
|
1243 | 1244 | tr.ui-sortable-helper { border:1px solid #e4e4e4; } |
|
1244 | 1245 | |
|
1245 |
.contextual> |
|
|
1246 | .contextual>*:not(:first-child), .buttons>.icon:not(:first-child) { margin-left: 5px; } | |
|
1246 | 1247 | |
|
1247 | 1248 | img.gravatar { |
|
1248 | 1249 | vertical-align: middle; |
@@ -221,6 +221,18 class MyControllerTest < Redmine::ControllerTest | |||
|
221 | 221 | end |
|
222 | 222 | end |
|
223 | 223 | |
|
224 | def test_update_page_with_blank_preferences | |
|
225 | user = User.generate!(:language => 'en') | |
|
226 | @request.session[:user_id] = user.id | |
|
227 | ||
|
228 | xhr :post, :update_page, :settings => {'timelog' => {'days' => '14'}} | |
|
229 | assert_response :success | |
|
230 | assert_include '$("#block-timelog").html(', response.body | |
|
231 | assert_include '14 days', response.body | |
|
232 | ||
|
233 | assert_equal({:days => "14"}, user.reload.pref.my_page_settings('timelog')) | |
|
234 | end | |
|
235 | ||
|
224 | 236 | def test_page_layout |
|
225 | 237 | get :page_layout |
|
226 | 238 | assert_response :success |
@@ -26,6 +26,7 class RoutingMyTest < Redmine::RoutingTest | |||
|
26 | 26 | should_route 'POST /my/account/destroy' => 'my#destroy' |
|
27 | 27 | |
|
28 | 28 | should_route 'GET /my/page' => 'my#page' |
|
29 | should_route 'POST /my/page' => 'my#update_page' | |
|
29 | 30 | should_route 'GET /my' => 'my#index' |
|
30 | 31 | |
|
31 | 32 | should_route 'GET /my/api_key' => 'my#show_api_key' |
General Comments 0
You need to be logged in to leave comments.
Login now