@@ -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 |
# |
|
|
2 |
# Copyright (C) 2006-200 |
|
|
1 | # Redmine - project management software | |
|
2 | # Copyright (C) 2006-2008 Jean-Philippe Lang | |
|
3 | 3 | # |
|
4 | 4 | # This program is free software; you can redistribute it and/or |
|
5 | 5 | # modify it under the terms of the GNU General Public License |
@@ -20,7 +20,7 class IssuesController < ApplicationController | |||
|
20 | 20 | |
|
21 | 21 | before_filter :find_issue, :only => [:show, :edit, :reply, :destroy_attachment] |
|
22 | 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 | 24 | before_filter :authorize, :except => [:index, :changes, :preview, :update_form, :context_menu] |
|
25 | 25 | before_filter :find_optional_project, :only => [:index, :changes] |
|
26 | 26 | accept_key_auth :index, :changes |
@@ -354,6 +354,33 class IssuesController < ApplicationController | |||
|
354 | 354 | end |
|
355 | 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 | 384 | def context_menu |
|
358 | 385 | @issues = Issue.find_all_by_id(params[:ids], :include => :project) |
|
359 | 386 | if (@issues.size == 1) |
@@ -27,7 +27,7 class ProjectsController < ApplicationController | |||
|
27 | 27 | before_filter :find_optional_project, :only => :activity |
|
28 | 28 | before_filter :authorize, :except => [ :index, :list, :add, :archive, :unarchive, :destroy, :activity ] |
|
29 | 29 | before_filter :require_admin, :only => [ :add, :archive, :unarchive, :destroy ] |
|
30 |
accept_key_auth :activity |
|
|
30 | accept_key_auth :activity | |
|
31 | 31 | |
|
32 | 32 | helper :sort |
|
33 | 33 | include SortHelper |
@@ -246,34 +246,6 class ProjectsController < ApplicationController | |||
|
246 | 246 | end |
|
247 | 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 | 249 | private |
|
278 | 250 | # Find project of id params[:id] |
|
279 | 251 | # if not found, redirect to project list |
@@ -1,5 +1,5 | |||
|
1 |
# |
|
|
2 |
# Copyright (C) 2006-200 |
|
|
1 | # Redmine - project management software | |
|
2 | # Copyright (C) 2006-2008 Jean-Philippe Lang | |
|
3 | 3 | # |
|
4 | 4 | # This program is free software; you can redistribute it and/or |
|
5 | 5 | # modify it under the terms of the GNU General Public License |
@@ -254,9 +254,8 class Query < ActiveRecord::Base | |||
|
254 | 254 | def has_default_columns? |
|
255 | 255 | column_names.nil? || column_names.empty? |
|
256 | 256 | end |
|
257 | ||
|
258 | def statement | |
|
259 | # project/subprojects clause | |
|
257 | ||
|
258 | def project_statement | |
|
260 | 259 | project_clauses = [] |
|
261 | 260 | if project && !@project.active_children.empty? |
|
262 | 261 | ids = [project.id] |
@@ -274,12 +273,15 class Query < ActiveRecord::Base | |||
|
274 | 273 | elsif Setting.display_subprojects_issues? |
|
275 | 274 | ids += project.child_ids |
|
276 | 275 | end |
|
277 |
project_clauses << "#{ |
|
|
276 | project_clauses << "#{Project.table_name}.id IN (%s)" % ids.join(',') | |
|
278 | 277 | elsif project |
|
279 |
project_clauses << "#{ |
|
|
278 | project_clauses << "#{Project.table_name}.id = %d" % project.id | |
|
280 | 279 | end |
|
281 | 280 | project_clauses << Project.visible_by(User.current) |
|
282 | ||
|
281 | project_clauses.join(' AND ') | |
|
282 | end | |
|
283 | ||
|
284 | def statement | |
|
283 | 285 | # filters clauses |
|
284 | 286 | filters_clauses = [] |
|
285 | 287 | filters.each_key do |field| |
@@ -356,7 +358,7 class Query < ActiveRecord::Base | |||
|
356 | 358 | filters_clauses << sql |
|
357 | 359 | end if filters and valid? |
|
358 | 360 | |
|
359 |
( |
|
|
361 | (filters_clauses << project_statement).join(' AND ') | |
|
360 | 362 | end |
|
361 | 363 | |
|
362 | 364 | private |
@@ -5,7 +5,7 | |||
|
5 | 5 | <%= link_to l(:label_change_log), :controller => 'projects', :action => 'changelog', :id => @project %> |
|
6 | 6 | |
|
7 | 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 | 9 | planning_links << link_to_if_authorized(l(:label_gantt), :action => 'gantt', :project_id => @project) |
|
10 | 10 | planning_links.compact! |
|
11 | 11 | unless planning_links.empty? %> |
@@ -6,7 +6,6 | |||
|
6 | 6 | </fieldset> |
|
7 | 7 | <% else %> |
|
8 | 8 | <h2><%=h @query.name %></h2> |
|
9 | <div id="query_form"></div> | |
|
10 | 9 | <% html_title @query.name %> |
|
11 | 10 | <% end %> |
|
12 | 11 |
@@ -57,7 +57,7 | |||
|
57 | 57 | |
|
58 | 58 | <% content_for :sidebar do %> |
|
59 | 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 | 61 | planning_links << link_to_if_authorized(l(:label_gantt), :controller => 'issues', :action => 'gantt', :project_id => @project) |
|
62 | 62 | planning_links.compact! |
|
63 | 63 | unless planning_links.empty? %> |
@@ -46,7 +46,7 Redmine::AccessControl.map do |map| | |||
|
46 | 46 | map.permission :save_queries, {:queries => [:new, :edit, :destroy]}, :require => :loggedin |
|
47 | 47 | # Gantt & calendar |
|
48 | 48 | map.permission :view_gantt, :issues => :gantt |
|
49 |
map.permission :view_calendar, : |
|
|
49 | map.permission :view_calendar, :issues => :calendar | |
|
50 | 50 | # Watchers |
|
51 | 51 | map.permission :view_issue_watchers, {} |
|
52 | 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 | 167 | fieldset#filters, fieldset#date-range { padding: 0.7em; margin-bottom: 8px; } |
|
168 | 168 | fieldset#filters p { margin: 1.2em 0 0.8em 2px; } |
|
169 | fieldset#filters .buttons { font-size: 0.9em; } | |
|
170 | 169 | fieldset#filters table { border-collapse: collapse; } |
|
171 | 170 | fieldset#filters table td { padding: 0; vertical-align: middle; } |
|
172 | 171 | fieldset#filters tr.filter { height: 2em; } |
|
173 | 172 | fieldset#filters td.add-filter { text-align: right; vertical-align: top; } |
|
173 | .buttons { font-size: 0.9em; } | |
|
174 | 174 | |
|
175 | 175 | div#issue-changesets {float:right; width:45%; margin-left: 1em; margin-bottom: 1em; background: #fff; padding-left: 1em; font-size: 90%;} |
|
176 | 176 | div#issue-changesets .changeset { padding: 4px;} |
@@ -341,7 +341,7 vertical-align: bottom; | |||
|
341 | 341 | } |
|
342 | 342 | |
|
343 | 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 | 345 | table.cal thead th {width: 14%;} |
|
346 | 346 | table.cal tbody tr {height: 100px;} |
|
347 | 347 | table.cal th { background-color:#EEEEEE; padding: 4px; } |
@@ -1,5 +1,5 | |||
|
1 |
# |
|
|
2 |
# Copyright (C) 2006-200 |
|
|
1 | # Redmine - project management software | |
|
2 | # Copyright (C) 2006-2008 Jean-Philippe Lang | |
|
3 | 3 | # |
|
4 | 4 | # This program is free software; you can redistribute it and/or |
|
5 | 5 | # modify it under the terms of the GNU General Public License |
@@ -161,6 +161,13 class IssuesControllerTest < Test::Unit::TestCase | |||
|
161 | 161 | puts "RMagick not installed. Skipping tests !!!" |
|
162 | 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 | 171 | def test_changes |
|
165 | 172 | get :changes, :project_id => 1 |
|
166 | 173 | assert_response :success |
@@ -1,5 +1,5 | |||
|
1 |
# |
|
|
2 |
# Copyright (C) 2006-200 |
|
|
1 | # Redmine - project management software | |
|
2 | # Copyright (C) 2006-2008 Jean-Philippe Lang | |
|
3 | 3 | # |
|
4 | 4 | # This program is free software; you can redistribute it and/or |
|
5 | 5 | # modify it under the terms of the GNU General Public License |
@@ -208,30 +208,6 class ProjectsControllerTest < Test::Unit::TestCase | |||
|
208 | 208 | assert_template 'common/feed.atom.rxml' |
|
209 | 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 | 211 | def test_archive |
|
236 | 212 | @request.session[:user_id] = 1 # admin |
|
237 | 213 | post :archive, :id => 1 |
|
1 | NO CONTENT: file was removed |
General Comments 0
You need to be logged in to leave comments.
Login now