@@ -0,0 +1,55 | |||||
|
1 | <% form_tag({}, :id => 'query_form') do %> | |||
|
2 | <% if @query.new_record? %> | |||
|
3 | <h2><%= l(:label_calendar) %></h2> | |||
|
4 | <fieldset id="filters"><legend><%= l(:label_filter_plural) %></legend> | |||
|
5 | <%= render :partial => 'queries/filters', :locals => {:query => @query} %> | |||
|
6 | </fieldset> | |||
|
7 | <% else %> | |||
|
8 | <h2><%=h @query.name %></h2> | |||
|
9 | <% html_title @query.name %> | |||
|
10 | <% end %> | |||
|
11 | ||||
|
12 | <fieldset id="date-range"><legend><%= l(:label_date_range) %></legend> | |||
|
13 | <%= select_month(@month, :prefix => "month", :discard_type => true) %> | |||
|
14 | <%= select_year(@year, :prefix => "year", :discard_type => true) %> | |||
|
15 | </fieldset> | |||
|
16 | ||||
|
17 | <p style="float:right; margin:0px;"> | |||
|
18 | <%= link_to_remote ('« ' + (@month==1 ? "#{month_name(12)} #{@year-1}" : "#{month_name(@month-1)}")), | |||
|
19 | {:update => "content", :url => { :year => (@month==1 ? @year-1 : @year), :month =>(@month==1 ? 12 : @month-1) }}, | |||
|
20 | {:href => url_for(:action => 'calendar', :year => (@month==1 ? @year-1 : @year), :month =>(@month==1 ? 12 : @month-1))} | |||
|
21 | %> | | |||
|
22 | <%= link_to_remote ((@month==12 ? "#{month_name(1)} #{@year+1}" : "#{month_name(@month+1)}") + ' »'), | |||
|
23 | {:update => "content", :url => { :year => (@month==12 ? @year+1 : @year), :month =>(@month==12 ? 1 : @month+1) }}, | |||
|
24 | {:href => url_for(:action => 'calendar', :year => (@month==12 ? @year+1 : @year), :month =>(@month==12 ? 1 : @month+1))} | |||
|
25 | %> | |||
|
26 | </p> | |||
|
27 | ||||
|
28 | <p class="buttons"> | |||
|
29 | <%= link_to_remote l(:button_apply), | |||
|
30 | { :url => { :set_filter => (@query.new_record? ? 1 : nil) }, | |||
|
31 | :update => "content", | |||
|
32 | :with => "Form.serialize('query_form')" | |||
|
33 | }, :class => 'icon icon-checked' %> | |||
|
34 | ||||
|
35 | <%= link_to_remote l(:button_clear), | |||
|
36 | { :url => { :set_filter => (@query.new_record? ? 1 : nil) }, | |||
|
37 | :update => "content", | |||
|
38 | }, :class => 'icon icon-reload' if @query.new_record? %> | |||
|
39 | </p> | |||
|
40 | <% end %> | |||
|
41 | ||||
|
42 | <%= error_messages_for 'query' %> | |||
|
43 | <% if @query.valid? %> | |||
|
44 | <%= render :partial => 'common/calendar', :locals => {:calendar => @calendar} %> | |||
|
45 | ||||
|
46 | <%= image_tag 'arrow_from.png' %> <%= l(:text_tip_task_begin_day) %><br /> | |||
|
47 | <%= image_tag 'arrow_to.png' %> <%= l(:text_tip_task_end_day) %><br /> | |||
|
48 | <%= image_tag 'arrow_bw.png' %> <%= l(:text_tip_task_begin_end_day) %><br /> | |||
|
49 | <% end %> | |||
|
50 | ||||
|
51 | <% content_for :sidebar do %> | |||
|
52 | <%= render :partial => 'issues/sidebar' %> | |||
|
53 | <% end %> | |||
|
54 | ||||
|
55 | <% html_title(l(:label_calendar)) -%> |
@@ -1,5 +1,5 | |||||
1 |
# |
|
1 | # Redmine - project management software | |
2 |
# Copyright (C) 2006-200 |
|
2 | # Copyright (C) 2006-2008 Jean-Philippe Lang | |
3 | # |
|
3 | # | |
4 | # This program is free software; you can redistribute it and/or |
|
4 | # This program is free software; you can redistribute it and/or | |
5 | # modify it under the terms of the GNU General Public License |
|
5 | # modify it under the terms of the GNU General Public License | |
@@ -20,7 +20,7 class IssuesController < ApplicationController | |||||
20 |
|
20 | |||
21 | before_filter :find_issue, :only => [:show, :edit, :reply, :destroy_attachment] |
|
21 | before_filter :find_issue, :only => [:show, :edit, :reply, :destroy_attachment] | |
22 | before_filter :find_issues, :only => [:bulk_edit, :move, :destroy] |
|
22 | before_filter :find_issues, :only => [:bulk_edit, :move, :destroy] | |
23 | before_filter :find_project, :only => [:new, :update_form, :preview, :gantt] |
|
23 | before_filter :find_project, :only => [:new, :update_form, :preview, :gantt, :calendar] | |
24 | before_filter :authorize, :except => [:index, :changes, :preview, :update_form, :context_menu] |
|
24 | before_filter :authorize, :except => [:index, :changes, :preview, :update_form, :context_menu] | |
25 | before_filter :find_optional_project, :only => [:index, :changes] |
|
25 | before_filter :find_optional_project, :only => [:index, :changes] | |
26 | accept_key_auth :index, :changes |
|
26 | accept_key_auth :index, :changes | |
@@ -354,6 +354,33 class IssuesController < ApplicationController | |||||
354 | end |
|
354 | end | |
355 | end |
|
355 | end | |
356 |
|
356 | |||
|
357 | def calendar | |||
|
358 | if params[:year] and params[:year].to_i > 1900 | |||
|
359 | @year = params[:year].to_i | |||
|
360 | if params[:month] and params[:month].to_i > 0 and params[:month].to_i < 13 | |||
|
361 | @month = params[:month].to_i | |||
|
362 | end | |||
|
363 | end | |||
|
364 | @year ||= Date.today.year | |||
|
365 | @month ||= Date.today.month | |||
|
366 | ||||
|
367 | @calendar = Redmine::Helpers::Calendar.new(Date.civil(@year, @month, 1), current_language, :month) | |||
|
368 | retrieve_query | |||
|
369 | if @query.valid? | |||
|
370 | events = [] | |||
|
371 | events += Issue.find(:all, | |||
|
372 | :include => [:tracker, :status, :assigned_to, :priority, :project], | |||
|
373 | :conditions => ["(#{@query.statement}) AND ((start_date BETWEEN ? AND ?) OR (due_date BETWEEN ? AND ?))", @calendar.startdt, @calendar.enddt, @calendar.startdt, @calendar.enddt] | |||
|
374 | ) | |||
|
375 | events += Version.find(:all, :include => :project, | |||
|
376 | :conditions => ["(#{@query.project_statement}) AND effective_date BETWEEN ? AND ?", @calendar.startdt, @calendar.enddt]) | |||
|
377 | ||||
|
378 | @calendar.events = events | |||
|
379 | end | |||
|
380 | ||||
|
381 | render :layout => false if request.xhr? | |||
|
382 | end | |||
|
383 | ||||
357 | def context_menu |
|
384 | def context_menu | |
358 | @issues = Issue.find_all_by_id(params[:ids], :include => :project) |
|
385 | @issues = Issue.find_all_by_id(params[:ids], :include => :project) | |
359 | if (@issues.size == 1) |
|
386 | if (@issues.size == 1) |
@@ -27,7 +27,7 class ProjectsController < ApplicationController | |||||
27 | before_filter :find_optional_project, :only => :activity |
|
27 | before_filter :find_optional_project, :only => :activity | |
28 | before_filter :authorize, :except => [ :index, :list, :add, :archive, :unarchive, :destroy, :activity ] |
|
28 | before_filter :authorize, :except => [ :index, :list, :add, :archive, :unarchive, :destroy, :activity ] | |
29 | before_filter :require_admin, :only => [ :add, :archive, :unarchive, :destroy ] |
|
29 | before_filter :require_admin, :only => [ :add, :archive, :unarchive, :destroy ] | |
30 |
accept_key_auth :activity |
|
30 | accept_key_auth :activity | |
31 |
|
31 | |||
32 | helper :sort |
|
32 | helper :sort | |
33 | include SortHelper |
|
33 | include SortHelper | |
@@ -246,34 +246,6 class ProjectsController < ApplicationController | |||||
246 | end |
|
246 | end | |
247 | end |
|
247 | end | |
248 |
|
248 | |||
249 | def calendar |
|
|||
250 | @trackers = @project.rolled_up_trackers |
|
|||
251 | retrieve_selected_tracker_ids(@trackers) |
|
|||
252 |
|
||||
253 | if params[:year] and params[:year].to_i > 1900 |
|
|||
254 | @year = params[:year].to_i |
|
|||
255 | if params[:month] and params[:month].to_i > 0 and params[:month].to_i < 13 |
|
|||
256 | @month = params[:month].to_i |
|
|||
257 | end |
|
|||
258 | end |
|
|||
259 | @year ||= Date.today.year |
|
|||
260 | @month ||= Date.today.month |
|
|||
261 | @calendar = Redmine::Helpers::Calendar.new(Date.civil(@year, @month, 1), current_language, :month) |
|
|||
262 | @with_subprojects = params[:with_subprojects].nil? ? Setting.display_subprojects_issues? : (params[:with_subprojects] == '1') |
|
|||
263 | events = [] |
|
|||
264 | @project.issues_with_subprojects(@with_subprojects) do |
|
|||
265 | events += Issue.find(:all, |
|
|||
266 | :include => [:tracker, :status, :assigned_to, :priority, :project], |
|
|||
267 | :conditions => ["((start_date BETWEEN ? AND ?) OR (due_date BETWEEN ? AND ?)) AND #{Issue.table_name}.tracker_id IN (#{@selected_tracker_ids.join(',')})", @calendar.startdt, @calendar.enddt, @calendar.startdt, @calendar.enddt] |
|
|||
268 | ) unless @selected_tracker_ids.empty? |
|
|||
269 | events += Version.find(:all, :include => :project, |
|
|||
270 | :conditions => ["effective_date BETWEEN ? AND ?", @calendar.startdt, @calendar.enddt]) |
|
|||
271 | end |
|
|||
272 | @calendar.events = events |
|
|||
273 |
|
||||
274 | render :layout => false if request.xhr? |
|
|||
275 | end |
|
|||
276 |
|
||||
277 | private |
|
249 | private | |
278 | # Find project of id params[:id] |
|
250 | # Find project of id params[:id] | |
279 | # if not found, redirect to project list |
|
251 | # if not found, redirect to project list |
@@ -1,5 +1,5 | |||||
1 |
# |
|
1 | # Redmine - project management software | |
2 |
# Copyright (C) 2006-200 |
|
2 | # Copyright (C) 2006-2008 Jean-Philippe Lang | |
3 | # |
|
3 | # | |
4 | # This program is free software; you can redistribute it and/or |
|
4 | # This program is free software; you can redistribute it and/or | |
5 | # modify it under the terms of the GNU General Public License |
|
5 | # modify it under the terms of the GNU General Public License | |
@@ -254,9 +254,8 class Query < ActiveRecord::Base | |||||
254 | def has_default_columns? |
|
254 | def has_default_columns? | |
255 | column_names.nil? || column_names.empty? |
|
255 | column_names.nil? || column_names.empty? | |
256 | end |
|
256 | end | |
257 |
|
257 | |||
258 | def statement |
|
258 | def project_statement | |
259 | # project/subprojects clause |
|
|||
260 | project_clauses = [] |
|
259 | project_clauses = [] | |
261 | if project && !@project.active_children.empty? |
|
260 | if project && !@project.active_children.empty? | |
262 | ids = [project.id] |
|
261 | ids = [project.id] | |
@@ -274,12 +273,15 class Query < ActiveRecord::Base | |||||
274 | elsif Setting.display_subprojects_issues? |
|
273 | elsif Setting.display_subprojects_issues? | |
275 | ids += project.child_ids |
|
274 | ids += project.child_ids | |
276 | end |
|
275 | end | |
277 |
project_clauses << "#{ |
|
276 | project_clauses << "#{Project.table_name}.id IN (%s)" % ids.join(',') | |
278 | elsif project |
|
277 | elsif project | |
279 |
project_clauses << "#{ |
|
278 | project_clauses << "#{Project.table_name}.id = %d" % project.id | |
280 | end |
|
279 | end | |
281 | project_clauses << Project.visible_by(User.current) |
|
280 | project_clauses << Project.visible_by(User.current) | |
282 |
|
281 | project_clauses.join(' AND ') | ||
|
282 | end | |||
|
283 | ||||
|
284 | def statement | |||
283 | # filters clauses |
|
285 | # filters clauses | |
284 | filters_clauses = [] |
|
286 | filters_clauses = [] | |
285 | filters.each_key do |field| |
|
287 | filters.each_key do |field| | |
@@ -356,7 +358,7 class Query < ActiveRecord::Base | |||||
356 | filters_clauses << sql |
|
358 | filters_clauses << sql | |
357 | end if filters and valid? |
|
359 | end if filters and valid? | |
358 |
|
360 | |||
359 |
( |
|
361 | (filters_clauses << project_statement).join(' AND ') | |
360 | end |
|
362 | end | |
361 |
|
363 | |||
362 | private |
|
364 | private |
@@ -5,7 +5,7 | |||||
5 | <%= link_to l(:label_change_log), :controller => 'projects', :action => 'changelog', :id => @project %> |
|
5 | <%= link_to l(:label_change_log), :controller => 'projects', :action => 'changelog', :id => @project %> | |
6 |
|
6 | |||
7 | <% planning_links = [] |
|
7 | <% planning_links = [] | |
8 |
planning_links << link_to_if_authorized(l(:label_calendar), |
|
8 | planning_links << link_to_if_authorized(l(:label_calendar), :action => 'calendar', :project_id => @project) | |
9 | planning_links << link_to_if_authorized(l(:label_gantt), :action => 'gantt', :project_id => @project) |
|
9 | planning_links << link_to_if_authorized(l(:label_gantt), :action => 'gantt', :project_id => @project) | |
10 | planning_links.compact! |
|
10 | planning_links.compact! | |
11 | unless planning_links.empty? %> |
|
11 | unless planning_links.empty? %> |
@@ -6,7 +6,6 | |||||
6 | </fieldset> |
|
6 | </fieldset> | |
7 | <% else %> |
|
7 | <% else %> | |
8 | <h2><%=h @query.name %></h2> |
|
8 | <h2><%=h @query.name %></h2> | |
9 | <div id="query_form"></div> |
|
|||
10 | <% html_title @query.name %> |
|
9 | <% html_title @query.name %> | |
11 | <% end %> |
|
10 | <% end %> | |
12 |
|
11 |
@@ -57,7 +57,7 | |||||
57 |
|
57 | |||
58 | <% content_for :sidebar do %> |
|
58 | <% content_for :sidebar do %> | |
59 | <% planning_links = [] |
|
59 | <% planning_links = [] | |
60 | planning_links << link_to_if_authorized(l(:label_calendar), :action => 'calendar', :id => @project) |
|
60 | planning_links << link_to_if_authorized(l(:label_calendar), :controller => 'issues', :action => 'calendar', :project_id => @project) | |
61 | planning_links << link_to_if_authorized(l(:label_gantt), :controller => 'issues', :action => 'gantt', :project_id => @project) |
|
61 | planning_links << link_to_if_authorized(l(:label_gantt), :controller => 'issues', :action => 'gantt', :project_id => @project) | |
62 | planning_links.compact! |
|
62 | planning_links.compact! | |
63 | unless planning_links.empty? %> |
|
63 | unless planning_links.empty? %> |
@@ -46,7 +46,7 Redmine::AccessControl.map do |map| | |||||
46 | map.permission :save_queries, {:queries => [:new, :edit, :destroy]}, :require => :loggedin |
|
46 | map.permission :save_queries, {:queries => [:new, :edit, :destroy]}, :require => :loggedin | |
47 | # Gantt & calendar |
|
47 | # Gantt & calendar | |
48 | map.permission :view_gantt, :issues => :gantt |
|
48 | map.permission :view_gantt, :issues => :gantt | |
49 |
map.permission :view_calendar, : |
|
49 | map.permission :view_calendar, :issues => :calendar | |
50 | # Watchers |
|
50 | # Watchers | |
51 | map.permission :view_issue_watchers, {} |
|
51 | map.permission :view_issue_watchers, {} | |
52 | map.permission :add_issue_watchers, {:watchers => :new} |
|
52 | map.permission :add_issue_watchers, {:watchers => :new} |
@@ -166,11 +166,11 p.subtitle { font-size: 0.9em; margin: -6px 0 12px 0; font-style: italic; } | |||||
166 |
|
166 | |||
167 | fieldset#filters, fieldset#date-range { padding: 0.7em; margin-bottom: 8px; } |
|
167 | fieldset#filters, fieldset#date-range { padding: 0.7em; margin-bottom: 8px; } | |
168 | fieldset#filters p { margin: 1.2em 0 0.8em 2px; } |
|
168 | fieldset#filters p { margin: 1.2em 0 0.8em 2px; } | |
169 | fieldset#filters .buttons { font-size: 0.9em; } |
|
|||
170 | fieldset#filters table { border-collapse: collapse; } |
|
169 | fieldset#filters table { border-collapse: collapse; } | |
171 | fieldset#filters table td { padding: 0; vertical-align: middle; } |
|
170 | fieldset#filters table td { padding: 0; vertical-align: middle; } | |
172 | fieldset#filters tr.filter { height: 2em; } |
|
171 | fieldset#filters tr.filter { height: 2em; } | |
173 | fieldset#filters td.add-filter { text-align: right; vertical-align: top; } |
|
172 | fieldset#filters td.add-filter { text-align: right; vertical-align: top; } | |
|
173 | .buttons { font-size: 0.9em; } | |||
174 |
|
174 | |||
175 | div#issue-changesets {float:right; width:45%; margin-left: 1em; margin-bottom: 1em; background: #fff; padding-left: 1em; font-size: 90%;} |
|
175 | div#issue-changesets {float:right; width:45%; margin-left: 1em; margin-bottom: 1em; background: #fff; padding-left: 1em; font-size: 90%;} | |
176 | div#issue-changesets .changeset { padding: 4px;} |
|
176 | div#issue-changesets .changeset { padding: 4px;} | |
@@ -341,7 +341,7 vertical-align: bottom; | |||||
341 | } |
|
341 | } | |
342 |
|
342 | |||
343 | /***** Calendar *****/ |
|
343 | /***** Calendar *****/ | |
344 |
table.cal {border-collapse: collapse; width: 100%; margin: |
|
344 | table.cal {border-collapse: collapse; width: 100%; margin: 0px 0 6px 0;border: 1px solid #d7d7d7;} | |
345 | table.cal thead th {width: 14%;} |
|
345 | table.cal thead th {width: 14%;} | |
346 | table.cal tbody tr {height: 100px;} |
|
346 | table.cal tbody tr {height: 100px;} | |
347 | table.cal th { background-color:#EEEEEE; padding: 4px; } |
|
347 | table.cal th { background-color:#EEEEEE; padding: 4px; } |
@@ -1,5 +1,5 | |||||
1 |
# |
|
1 | # Redmine - project management software | |
2 |
# Copyright (C) 2006-200 |
|
2 | # Copyright (C) 2006-2008 Jean-Philippe Lang | |
3 | # |
|
3 | # | |
4 | # This program is free software; you can redistribute it and/or |
|
4 | # This program is free software; you can redistribute it and/or | |
5 | # modify it under the terms of the GNU General Public License |
|
5 | # modify it under the terms of the GNU General Public License | |
@@ -161,6 +161,13 class IssuesControllerTest < Test::Unit::TestCase | |||||
161 | puts "RMagick not installed. Skipping tests !!!" |
|
161 | puts "RMagick not installed. Skipping tests !!!" | |
162 | end |
|
162 | end | |
163 |
|
163 | |||
|
164 | def test_calendar | |||
|
165 | get :calendar, :project_id => 1 | |||
|
166 | assert_response :success | |||
|
167 | assert_template 'calendar' | |||
|
168 | assert_not_nil assigns(:calendar) | |||
|
169 | end | |||
|
170 | ||||
164 | def test_changes |
|
171 | def test_changes | |
165 | get :changes, :project_id => 1 |
|
172 | get :changes, :project_id => 1 | |
166 | assert_response :success |
|
173 | assert_response :success |
@@ -1,5 +1,5 | |||||
1 |
# |
|
1 | # Redmine - project management software | |
2 |
# Copyright (C) 2006-200 |
|
2 | # Copyright (C) 2006-2008 Jean-Philippe Lang | |
3 | # |
|
3 | # | |
4 | # This program is free software; you can redistribute it and/or |
|
4 | # This program is free software; you can redistribute it and/or | |
5 | # modify it under the terms of the GNU General Public License |
|
5 | # modify it under the terms of the GNU General Public License | |
@@ -208,30 +208,6 class ProjectsControllerTest < Test::Unit::TestCase | |||||
208 | assert_template 'common/feed.atom.rxml' |
|
208 | assert_template 'common/feed.atom.rxml' | |
209 | end |
|
209 | end | |
210 |
|
210 | |||
211 | def test_calendar |
|
|||
212 | get :calendar, :id => 1 |
|
|||
213 | assert_response :success |
|
|||
214 | assert_template 'calendar' |
|
|||
215 | assert_not_nil assigns(:calendar) |
|
|||
216 | end |
|
|||
217 |
|
||||
218 | def test_calendar_with_subprojects_should_not_show_private_subprojects |
|
|||
219 | get :calendar, :id => 1, :with_subprojects => 1, :tracker_ids => [1, 2] |
|
|||
220 | assert_response :success |
|
|||
221 | assert_template 'calendar' |
|
|||
222 | assert_not_nil assigns(:calendar) |
|
|||
223 | assert_no_tag :tag => 'a', :content => /#6/ |
|
|||
224 | end |
|
|||
225 |
|
||||
226 | def test_calendar_with_subprojects_should_show_private_subprojects |
|
|||
227 | @request.session[:user_id] = 2 |
|
|||
228 | get :calendar, :id => 1, :with_subprojects => 1, :tracker_ids => [1, 2] |
|
|||
229 | assert_response :success |
|
|||
230 | assert_template 'calendar' |
|
|||
231 | assert_not_nil assigns(:calendar) |
|
|||
232 | assert_tag :tag => 'a', :content => /#6/ |
|
|||
233 | end |
|
|||
234 |
|
||||
235 | def test_archive |
|
211 | def test_archive | |
236 | @request.session[:user_id] = 1 # admin |
|
212 | @request.session[:user_id] = 1 # admin | |
237 | post :archive, :id => 1 |
|
213 | post :archive, :id => 1 |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
General Comments 0
You need to be logged in to leave comments.
Login now