@@ -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 | redirect_to my_account_path |
|
130 | redirect_to my_account_path | |
131 | end |
|
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 | # User's page layout configuration |
|
144 | # User's page layout configuration | |
134 | def page_layout |
|
145 | def page_layout | |
135 | @user = User.current |
|
146 | @user = User.current |
@@ -45,8 +45,9 module MyHelper | |||||
45 | return |
|
45 | return | |
46 | end |
|
46 | end | |
47 |
|
47 | |||
|
48 | settings = user.pref.my_page_settings(block) | |||
48 | begin |
|
49 | begin | |
49 | render(:partial => "my/blocks/#{block}", :locals => {:user => user}) |
|
50 | render(:partial => "my/blocks/#{block}", :locals => {:user => user, :settings => settings}) | |
50 | rescue ActionView::MissingTemplate |
|
51 | rescue ActionView::MissingTemplate | |
51 | Rails.logger.warn("Template missing for block \"#{block}\" found in #{user.login} (id=#{user.id}) preferences") |
|
52 | Rails.logger.warn("Template missing for block \"#{block}\" found in #{user.login} (id=#{user.id}) preferences") | |
52 | return nil |
|
53 | return nil | |
@@ -107,13 +108,18 module MyHelper | |||||
107 | to_a |
|
108 | to_a | |
108 | end |
|
109 | end | |
109 |
|
110 | |||
110 | def timelog_items |
|
111 | def timelog_items(settings) | |
111 | TimeEntry. |
|
112 | days = settings[:days].to_i | |
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). |
|
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 | joins(:activity, :project). |
|
117 | joins(:activity, :project). | |
114 | references(:issue => [:tracker, :status]). |
|
118 | references(:issue => [:tracker, :status]). | |
115 | includes(:issue => [:tracker, :status]). |
|
119 | includes(:issue => [:tracker, :status]). | |
116 | order("#{TimeEntry.table_name}.spent_on DESC, #{Project.table_name}.name ASC, #{Tracker.table_name}.position ASC, #{Issue.table_name}.id ASC"). |
|
120 | order("#{TimeEntry.table_name}.spent_on DESC, #{Project.table_name}.name ASC, #{Tracker.table_name}.position ASC, #{Issue.table_name}.id ASC"). | |
117 | to_a |
|
121 | to_a | |
|
122 | ||||
|
123 | return entries, days | |||
118 | end |
|
124 | end | |
119 | end |
|
125 | end |
@@ -91,6 +91,19 class UserPreference < ActiveRecord::Base | |||||
91 | self[:my_page_layout] = arg |
|
91 | self[:my_page_layout] = arg | |
92 | end |
|
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 | def remove_block(block) |
|
107 | def remove_block(block) | |
95 | block = block.to_s.underscore |
|
108 | block = block.to_s.underscore | |
96 | %w(top left right).each do |f| |
|
109 | %w(top left right).each do |f| | |
@@ -108,4 +121,9 class UserPreference < ActiveRecord::Base | |||||
108 | my_page_layout['top'] ||= [] |
|
121 | my_page_layout['top'] ||= [] | |
109 | my_page_layout['top'].unshift(block) |
|
122 | my_page_layout['top'].unshift(block) | |
110 | end |
|
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 | end |
|
129 | end |
@@ -1,18 +1,37 | |||||
1 | <% |
|
1 | <% | |
2 | entries = timelog_items |
|
2 | entries, days = timelog_items(settings) | |
3 | entries_by_day = entries.group_by(&:spent_on) |
|
3 | entries_by_day = entries.group_by(&:spent_on) | |
4 | %> |
|
4 | %> | |
5 | <% if User.current.allowed_to?(:log_time, nil, :global => true) %> |
|
5 | ||
6 | <div class="contextual"> |
|
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 | </div> |
|
9 | </div> | |
9 | <% end %> |
|
|||
10 |
|
10 | |||
11 | <h3> |
|
11 | <h3> | |
12 | <%= link_to l(:label_spent_time), time_entries_path(:user_id => 'me') %> |
|
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 | </h3> |
|
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 | <% if entries.any? %> |
|
35 | <% if entries.any? %> | |
17 | <%= form_tag({}, :data => {:cm_url => time_entries_context_menu_path}) do %> |
|
36 | <%= form_tag({}, :data => {:cm_url => time_entries_context_menu_path}) do %> | |
18 | <table class="list time-entries"> |
|
37 | <table class="list time-entries"> |
@@ -74,6 +74,7 Rails.application.routes.draw do | |||||
74 | match 'my/account', :controller => 'my', :action => 'account', :via => [:get, :post] |
|
74 | match 'my/account', :controller => 'my', :action => 'account', :via => [:get, :post] | |
75 | match 'my/account/destroy', :controller => 'my', :action => 'destroy', :via => [:get, :post] |
|
75 | match 'my/account/destroy', :controller => 'my', :action => 'destroy', :via => [:get, :post] | |
76 | match 'my/page', :controller => 'my', :action => 'page', :via => :get |
|
76 | match 'my/page', :controller => 'my', :action => 'page', :via => :get | |
|
77 | post 'my/page', :to => 'my#update_page' | |||
77 | match 'my', :controller => 'my', :action => 'index', :via => :get # Redirects to my/page |
|
78 | match 'my', :controller => 'my', :action => 'index', :via => :get # Redirects to my/page | |
78 | get 'my/api_key', :to => 'my#show_api_key', :as => 'my_api_key' |
|
79 | get 'my/api_key', :to => 'my#show_api_key', :as => 'my_api_key' | |
79 | post 'my/api_key', :to => 'my#reset_api_key' |
|
80 | post 'my/api_key', :to => 'my#reset_api_key' |
@@ -1218,6 +1218,7 div.wiki img {vertical-align:middle; max-width:100%;} | |||||
1218 | .icon-list { background-image: url(../images/text_list_bullets.png); } |
|
1218 | .icon-list { background-image: url(../images/text_list_bullets.png); } | |
1219 | .icon-close { background-image: url(../images/close.png); } |
|
1219 | .icon-close { background-image: url(../images/close.png); } | |
1220 | .icon-close:hover { background-image: url(../images/close_hl.png); } |
|
1220 | .icon-close:hover { background-image: url(../images/close_hl.png); } | |
|
1221 | .icon-settings { background-image: url(../images/changeset.png); } | |||
1221 |
|
1222 | |||
1222 | .icon-file { background-image: url(../images/files/default.png); } |
|
1223 | .icon-file { background-image: url(../images/files/default.png); } | |
1223 | .icon-file.text-plain { background-image: url(../images/files/text.png); } |
|
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 | .sort-handle.ajax-loading { background-image: url(../images/loading.gif); } |
|
1243 | .sort-handle.ajax-loading { background-image: url(../images/loading.gif); } | |
1243 | tr.ui-sortable-helper { border:1px solid #e4e4e4; } |
|
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 | img.gravatar { |
|
1248 | img.gravatar { | |
1248 | vertical-align: middle; |
|
1249 | vertical-align: middle; |
@@ -221,6 +221,18 class MyControllerTest < Redmine::ControllerTest | |||||
221 | end |
|
221 | end | |
222 | end |
|
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 | def test_page_layout |
|
236 | def test_page_layout | |
225 | get :page_layout |
|
237 | get :page_layout | |
226 | assert_response :success |
|
238 | assert_response :success |
@@ -26,6 +26,7 class RoutingMyTest < Redmine::RoutingTest | |||||
26 | should_route 'POST /my/account/destroy' => 'my#destroy' |
|
26 | should_route 'POST /my/account/destroy' => 'my#destroy' | |
27 |
|
27 | |||
28 | should_route 'GET /my/page' => 'my#page' |
|
28 | should_route 'GET /my/page' => 'my#page' | |
|
29 | should_route 'POST /my/page' => 'my#update_page' | |||
29 | should_route 'GET /my' => 'my#index' |
|
30 | should_route 'GET /my' => 'my#index' | |
30 |
|
31 | |||
31 | should_route 'GET /my/api_key' => 'my#show_api_key' |
|
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