* added an helper and moved the rendering code to a shared partial (used by project calendar and my calendar) * first day of week can now be set in lang files (general_first_day_of_week) git-svn-id: http://redmine.rubyforge.org/svn/trunk@815 e93f8b46-1217-0410-a6f0-8f06a7374b81tags/0.6.0
@@ -16,6 +16,8 @@ | |||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
class MyController < ApplicationController | |||
helper :issues | |||
layout 'base' | |||
before_filter :require_login | |||
@@ -512,26 +512,18 @@ class ProjectsController < ApplicationController | |||
end | |||
end | |||
@year ||= Date.today.year | |||
@month ||= Date.today.month | |||
@date_from = Date.civil(@year, @month, 1) | |||
@date_to = (@date_from >> 1)-1 | |||
# start on monday | |||
@date_from = @date_from - (@date_from.cwday-1) | |||
# finish on sunday | |||
@date_to = @date_to + (7-@date_to.cwday) | |||
@month ||= Date.today.month | |||
@calendar = Redmine::Helpers::Calendar.new(Date.civil(@year, @month, 1), current_language, :month) | |||
@events = [] | |||
events = [] | |||
@project.issues_with_subprojects(params[:with_subprojects]) do | |||
@events += Issue.find(:all, | |||
events += Issue.find(:all, | |||
:include => [:tracker, :status, :assigned_to, :priority, :project], | |||
:conditions => ["((start_date>=? and start_date<=?) or (due_date>=? and due_date<=?)) and #{Issue.table_name}.tracker_id in (#{@selected_tracker_ids.join(',')})", @date_from, @date_to, @date_from, @date_to] | |||
: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] | |||
) unless @selected_tracker_ids.empty? | |||
end | |||
@events += @project.versions.find(:all, :conditions => ["effective_date BETWEEN ? AND ?", @date_from, @date_to]) | |||
@ending_events_by_days = @events.group_by {|event| event.due_date} | |||
@starting_events_by_days = @events.group_by {|event| event.start_date} | |||
events += @project.versions.find(:all, :conditions => ["effective_date BETWEEN ? AND ?", @calendar.startdt, @calendar.enddt]) | |||
@calendar.events = events | |||
render :layout => false if request.xhr? | |||
end |
@@ -0,0 +1,36 @@ | |||
<table class="cal"> | |||
<thead> | |||
<tr><td></td><% 7.times do |i| %><th><%= day_name( (calendar.first_wday+i)%7 ) %></th><% end %></tr> | |||
</thead> | |||
<tbody> | |||
<tr> | |||
<% day = calendar.startdt | |||
while day <= calendar.enddt %> | |||
<%= "<th>#{day.cweek}</th>" if day.cwday == calendar.first_wday %> | |||
<td class="<%= day.month==calendar.month ? 'even' : 'odd' %><%= ' today' if Date.today == day %>"> | |||
<p class="day-num"><%= day.day %></p> | |||
<% calendar.events_on(day).each do |i| %> | |||
<% if i.is_a? Issue %> | |||
<div class="tooltip"> | |||
<%= if day == i.start_date && day == i.due_date | |||
image_tag('arrow_bw.png') | |||
elsif day == i.start_date | |||
image_tag('arrow_from.png') | |||
elsif day == i.due_date | |||
image_tag('arrow_to.png') | |||
end %> | |||
<%= h("#{i.project.name} -") unless @project && @project == i.project %> | |||
<%= link_to_issue i %>: <%= h(truncate(i.subject, 30)) %> | |||
<span class="tip"><%= render_issue_tooltip i %></span> | |||
</div> | |||
<% else %> | |||
<%= link_to_version i, :class => "icon icon-package" %> | |||
<% end %> | |||
<% end %> | |||
</td> | |||
<%= '</tr><tr>' if day.cwday==calendar.last_wday and day!=calendar.enddt %> | |||
<% day = day + 1 | |||
end %> | |||
</tr> | |||
</tbody> | |||
</table> |
@@ -1,47 +1,8 @@ | |||
<h3><%= l(:label_calendar) %></h3> | |||
<% | |||
@date_from = Date.today - (Date.today.cwday-1) | |||
@date_to = Date.today + (7-Date.today.cwday) | |||
@issues = Issue.find :all, | |||
:conditions => ["#{Issue.table_name}.project_id in (#{@user.projects.collect{|m| m.id}.join(',')}) AND ((start_date>=? and start_date<=?) or (due_date>=? and due_date<=?))", @date_from, @date_to, @date_from, @date_to], | |||
:include => [:project, :tracker] unless @user.projects.empty? | |||
@issues ||= [] | |||
%> | |||
<% calendar = Redmine::Helpers::Calendar.new(Date.today, current_language, :week) | |||
calendar.events = Issue.find :all, | |||
:conditions => ["#{Issue.table_name}.project_id in (#{@user.projects.collect{|m| m.id}.join(',')}) AND ((start_date>=? and start_date<=?) or (due_date>=? and due_date<=?))", calendar.startdt, calendar.enddt, calendar.startdt, calendar.enddt], | |||
:include => [:project, :tracker, :priority, :assigned_to] unless @user.projects.empty? %> | |||
<table class="cal"> | |||
<thead><tr> | |||
<td></td> | |||
<% 1.upto(7) do |d| %> | |||
<th align="center" width="14%"><%= day_name(d) %></th> | |||
<% end %> | |||
</tr></thead> | |||
<tbdoy> | |||
<tr height="100"> | |||
<% day = @date_from | |||
while day <= @date_to | |||
if day.cwday == 1 %> | |||
<th valign="middle"><%= day.cweek %></th> | |||
<% end %> | |||
<td valign="top" width="14%" class="<%= day.month==@month ? "even" : "odd" %>"> | |||
<p align="right"><%= day==Date.today ? "<b>#{day.day}</b>" : day.day %></p> | |||
<% day_issues = [] | |||
@issues.each { |i| day_issues << i if i.start_date == day or i.due_date == day } | |||
day_issues.each do |i| %> | |||
<%= if day == i.start_date and day == i.due_date | |||
image_tag('arrow_bw.png') | |||
elsif day == i.start_date | |||
image_tag('arrow_from.png') | |||
elsif day == i.due_date | |||
image_tag('arrow_to.png') | |||
end %> | |||
<small><%= link_to_issue i %>: <%=h i.subject.sub(/^(.{30}[^\s]*\s).*$/, '\1 (...)') %></small><br /> | |||
<% end %> | |||
</td> | |||
<%= '</tr><tr height="100">' if day.cwday >= 7 and day!=@date_to %> | |||
<% | |||
day = day + 1 | |||
end %> | |||
</tr> | |||
</tbody> | |||
</table> | |||
<%= render :partial => 'common/calendar', :locals => {:calendar => calendar } %> |
@@ -15,55 +15,7 @@ | |||
</td></tr> | |||
</table> | |||
<table class="cal"> | |||
<thead> | |||
<tr> | |||
<td></td> | |||
<% 1.upto(7) do |d| %> | |||
<th style="width:14%"><%= day_name(d) %></th> | |||
<% end %> | |||
</tr> | |||
</thead> | |||
<tbody> | |||
<tr style="height:100px"> | |||
<% day = @date_from | |||
while day <= @date_to | |||
if day.cwday == 1 %> | |||
<th><%= day.cweek %></th> | |||
<% end %> | |||
<td valign="top" class="<%= day.month==@month ? "even" : "odd" %> <%= Date.today == day ? 'today' : '' %>" style="width:14%;"> | |||
<p class="textright"><%= day==Date.today ? "<b>#{day.day}</b>" : day.day %></p> | |||
<% ((@ending_events_by_days[day] || []) + (@starting_events_by_days[day] || [])).uniq.each do |i| %> | |||
<% if i.is_a? Issue %> | |||
<div class="tooltip"> | |||
<%= if day == i.start_date and day == i.due_date | |||
image_tag('arrow_bw.png') | |||
elsif day == i.start_date | |||
image_tag('arrow_from.png') | |||
elsif day == i.due_date | |||
image_tag('arrow_to.png') | |||
end %> | |||
<small> | |||
<%= h("#{i.project.name} -") unless @project && @project == i.project %> | |||
<%= link_to_issue i %>: | |||
<%= h(truncate(i.subject, 30)) %> | |||
</small> | |||
<span class="tip"> | |||
<%= render_issue_tooltip i %> | |||
</span> | |||
</div> | |||
<% else %> | |||
<small><%= link_to_version i, :class => "icon icon-package" %></small> | |||
<% end %> | |||
<% end %> | |||
</td> | |||
<%= '</tr><tr style="height:100px">' if day.cwday >= 7 and day!=@date_to %> | |||
<% | |||
day = day + 1 | |||
end %> | |||
</tr> | |||
</tbody> | |||
</table> | |||
<%= render :partial => 'common/calendar', :locals => {:calendar => @calendar} %> | |||
<%= image_tag 'arrow_from.png' %> <%= l(:text_tip_task_begin_day) %><br /> | |||
<%= image_tag 'arrow_to.png' %> <%= l(:text_tip_task_end_day) %><br /> |
@@ -51,6 +51,7 @@ general_csv_separator: ',' | |||
general_csv_encoding: ISO-8859-1 | |||
general_pdf_encoding: ISO-8859-1 | |||
general_day_names: Понеделник,Вторник,Сряда,Четвъртък,Петък,Събота,Неделя | |||
general_first_day_of_week: '1' | |||
notice_account_updated: Профилът е обновен успешно. | |||
notice_account_invalid_creditentials: Невалиден потребител или парола. |
@@ -51,6 +51,7 @@ general_csv_separator: ',' | |||
general_csv_encoding: UTF-8 | |||
general_pdf_encoding: UTF-8 | |||
general_day_names: Pondělí,Úterý,Středa,Čtvrtek,Pátek,Sobota,Neděle | |||
general_first_day_of_week: '1' | |||
notice_account_updated: Účet byl úspěšně změněn. | |||
notice_account_invalid_creditentials: Chybné jméno nebo heslo |
@@ -51,6 +51,7 @@ general_csv_separator: ';' | |||
general_csv_encoding: ISO-8859-1 | |||
general_pdf_encoding: ISO-8859-1 | |||
general_day_names: Montag,Dienstag,Mittwoch,Donnerstag,Freitag,Samstag,Sonntag | |||
general_first_day_of_week: '1' | |||
notice_account_updated: Konto wurde erfolgreich aktualisiert. | |||
notice_account_invalid_creditentials: Benutzer oder Kennwort unzulässig |
@@ -51,6 +51,7 @@ general_csv_separator: ',' | |||
general_csv_encoding: ISO-8859-1 | |||
general_pdf_encoding: ISO-8859-1 | |||
general_day_names: Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday | |||
general_first_day_of_week: '7' | |||
notice_account_updated: Account was successfully updated. | |||
notice_account_invalid_creditentials: Invalid user or password |
@@ -51,6 +51,7 @@ general_csv_separator: ';' | |||
general_csv_encoding: ISO-8859-15 | |||
general_pdf_encoding: ISO-8859-15 | |||
general_day_names: Lunes,Martes,Miércoles,Jueves,Viernes,Sábado,Domingo | |||
general_first_day_of_week: '1' | |||
notice_account_updated: Cuenta creada correctamente. | |||
notice_account_invalid_creditentials: Inválido usuario o contraseña |
@@ -51,6 +51,7 @@ general_csv_separator: ';' | |||
general_csv_encoding: ISO-8859-1 | |||
general_pdf_encoding: ISO-8859-1 | |||
general_day_names: Lundi,Mardi,Mercredi,Jeudi,Vendredi,Samedi,Dimanche | |||
general_first_day_of_week: '1' | |||
notice_account_updated: Le compte a été mis à jour avec succès. | |||
notice_account_invalid_creditentials: Identifiant ou mot de passe invalide. |
@@ -51,6 +51,7 @@ general_csv_separator: ',' | |||
general_csv_encoding: ISO-8859-1 | |||
general_pdf_encoding: ISO-8859-1 | |||
general_day_names: Lunedì,Martedì,Mercoledì,Giovedì,Venerdì,Sabato,Domenica | |||
general_first_day_of_week: '1' | |||
notice_account_updated: L'utenza è stata aggiornata. | |||
notice_account_invalid_creditentials: Nome utente o password non validi. |
@@ -52,6 +52,7 @@ general_csv_separator: ',' | |||
general_csv_encoding: SJIS | |||
general_pdf_encoding: SJIS | |||
general_day_names: 月曜日,火曜日,水曜日,木曜日,金曜日,土曜日,日曜日 | |||
general_first_day_of_week: '7' | |||
notice_account_updated: アカウントが更新されました。 | |||
notice_account_invalid_creditentials: ユーザ名もしくはパスワードが無効 |
@@ -51,6 +51,7 @@ general_csv_separator: ',' | |||
general_csv_encoding: ISO-8859-1 | |||
general_pdf_encoding: ISO-8859-1 | |||
general_day_names: Maandag, Dinsdag, Woensdag, Donderdag, Vrijdag, Zaterdag, Zondag | |||
general_first_day_of_week: '7' | |||
notice_account_updated: Account is met succes gewijzigd | |||
notice_account_invalid_creditentials: Incorrecte gebruikersnaam of wachtwoord |
@@ -51,6 +51,7 @@ general_csv_separator: ',' | |||
general_csv_encoding: ISO-8859-2 | |||
general_pdf_encoding: ISO-8859-2 | |||
general_day_names: Poniedziałek,Wtorek,Środa,Czwartek,Piątek,Sobota,Niedziela | |||
general_first_day_of_week: '1' | |||
notice_account_updated: Konto prawidłowo zaktualizowane. | |||
notice_account_invalid_creditentials: Zły użytkownik lub hasło |
@@ -51,6 +51,7 @@ general_csv_separator: ',' | |||
general_csv_encoding: ISO-8859-1 | |||
general_pdf_encoding: ISO-8859-1 | |||
general_day_names: Segunda,Terca,Quarta,Quinta,Sexta,Sabado,Domingo | |||
general_first_day_of_week: '1' | |||
notice_account_updated: Conta foi alterada com sucesso. | |||
notice_account_invalid_creditentials: Usuario ou senha invalido. |
@@ -51,6 +51,7 @@ general_csv_separator: ',' | |||
general_csv_encoding: ISO-8859-1 | |||
general_pdf_encoding: ISO-8859-1 | |||
general_day_names: Segunda,Terça,Quarta,Quinta,Sexta,Sábado,Domingo | |||
general_first_day_of_week: '1' | |||
notice_account_updated: Conta foi atualizada com sucesso. | |||
notice_account_invalid_creditentials: Usuário ou senha inválidos. |
@@ -51,6 +51,7 @@ general_csv_separator: ',' | |||
general_csv_encoding: ISO-8859-1 | |||
general_pdf_encoding: ISO-8859-1 | |||
general_day_names: Luni,Marti,Miercuri,Joi,Vineri,Sambata,Duminica | |||
general_first_day_of_week: '7' | |||
notice_account_updated: Contul a fost creat cu succes. | |||
notice_account_invalid_creditentials: Numele utilizator sau parola este invalida. |
@@ -51,6 +51,7 @@ general_csv_separator: ',' | |||
general_csv_encoding: ISO-8859-1 | |||
general_pdf_encoding: ISO-8859-1 | |||
general_day_names: Måndag,Tisdag,Onsdag,Torsdag,Fredag,Lördag,Söndag | |||
general_first_day_of_week: '7' | |||
notice_account_updated: Kontot har uppdaterats | |||
notice_account_invalid_creditentials: Fel användarnamn eller lösenord |
@@ -54,6 +54,7 @@ general_csv_separator: ',' | |||
general_csv_encoding: gb2312 | |||
general_pdf_encoding: Big5 | |||
general_day_names: 一,二,三,四,五,六,日 | |||
general_first_day_of_week: '7' | |||
notice_account_updated: 帐户更新成功。 | |||
notice_account_invalid_creditentials: 用户名或密码不正确 |
@@ -0,0 +1,76 @@ | |||
# redMine - project management software | |||
# Copyright (C) 2006-2007 Jean-Philippe Lang | |||
# | |||
# This program is free software; you can redistribute it and/or | |||
# modify it under the terms of the GNU General Public License | |||
# as published by the Free Software Foundation; either version 2 | |||
# of the License, or (at your option) any later version. | |||
# | |||
# This program is distributed in the hope that it will be useful, | |||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
# GNU General Public License for more details. | |||
# | |||
# You should have received a copy of the GNU General Public License | |||
# along with this program; if not, write to the Free Software | |||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
module Redmine | |||
module Helpers | |||
# Simple class to compute the start and end dates of a calendar | |||
class Calendar | |||
include GLoc | |||
attr_reader :startdt, :enddt | |||
def initialize(date, lang = current_language, period = :month) | |||
@date = date | |||
@events = [] | |||
@ending_events_by_days = {} | |||
@starting_events_by_days = {} | |||
set_language lang | |||
case period | |||
when :month | |||
@startdt = Date.civil(date.year, date.month, 1) | |||
@enddt = (@startdt >> 1)-1 | |||
# starts from the first day of the week | |||
@startdt = @startdt - (@startdt.cwday - first_wday)%7 | |||
# ends on the last day of the week | |||
@enddt = @enddt + (last_wday - @enddt.cwday)%7 | |||
when :week | |||
@startdt = date - (date.cwday - first_wday)%7 | |||
@enddt = date + (last_wday - date.cwday)%7 | |||
else | |||
raise 'Invalid period' | |||
end | |||
end | |||
# Sets calendar events | |||
def events=(events) | |||
@events = events | |||
@ending_events_by_days = @events.group_by {|event| event.due_date} | |||
@starting_events_by_days = @events.group_by {|event| event.start_date} | |||
end | |||
# Returns events for the given day | |||
def events_on(day) | |||
((@ending_events_by_days[day] || []) + (@starting_events_by_days[day] || [])).uniq | |||
end | |||
# Calendar current month | |||
def month | |||
@date.month | |||
end | |||
# Return the first day of week | |||
# 1 = Monday ... 7 = Sunday | |||
def first_wday | |||
@first_dow ||= (l(:general_first_day_of_week).to_i - 1)%7 + 1 | |||
end | |||
def last_wday | |||
@last_dow ||= (first_wday + 5)%7 + 1 | |||
end | |||
end | |||
end | |||
end |
@@ -212,9 +212,14 @@ vertical-align: bottom; | |||
/***** Calendar *****/ | |||
table.cal {border-collapse: collapse; width: 100%; margin: 8px 0 6px 0;border: 1px solid #d7d7d7;} | |||
table.cal thead th {width: 14%;} | |||
table.cal tbody tr {height: 100px;} | |||
table.cal th { background-color:#EEEEEE; padding: 4px; } | |||
table.cal td {border: 1px solid #d7d7d7;} | |||
table.cal td {border: 1px solid #d7d7d7; vertical-align: top; font-size: 0.9em;} | |||
table.cal td p.day-num {font-size: 1.1em; text-align:right;} | |||
table.cal td.odd p.day-num {color: #bbb;} | |||
table.cal td.today {background:#ffffdd;} | |||
table.cal td.today p.day-num {font-weight: bold;} | |||
/***** Tooltips ******/ | |||
.tooltip{position:relative;z-index:24;} |
@@ -0,0 +1,43 @@ | |||
# redMine - project management software | |||
# Copyright (C) 2006-2007 Jean-Philippe Lang | |||
# | |||
# This program is free software; you can redistribute it and/or | |||
# modify it under the terms of the GNU General Public License | |||
# as published by the Free Software Foundation; either version 2 | |||
# of the License, or (at your option) any later version. | |||
# | |||
# This program is distributed in the hope that it will be useful, | |||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
# GNU General Public License for more details. | |||
# | |||
# You should have received a copy of the GNU General Public License | |||
# along with this program; if not, write to the Free Software | |||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
require File.dirname(__FILE__) + '/../test_helper' | |||
class CalendarTest < Test::Unit::TestCase | |||
def test_monthly | |||
c = Redmine::Helpers::Calendar.new(Date.today, :fr, :month) | |||
assert_equal [1, 7], [c.startdt.cwday, c.enddt.cwday] | |||
c = Redmine::Helpers::Calendar.new('2007-07-14'.to_date, :fr, :month) | |||
assert_equal ['2007-06-25'.to_date, '2007-08-05'.to_date], [c.startdt, c.enddt] | |||
c = Redmine::Helpers::Calendar.new(Date.today, :en, :month) | |||
assert_equal [7, 6], [c.startdt.cwday, c.enddt.cwday] | |||
end | |||
def test_weekly | |||
c = Redmine::Helpers::Calendar.new(Date.today, :fr, :week) | |||
assert_equal [1, 7], [c.startdt.cwday, c.enddt.cwday] | |||
c = Redmine::Helpers::Calendar.new('2007-07-14'.to_date, :fr, :week) | |||
assert_equal ['2007-07-09'.to_date, '2007-07-15'.to_date], [c.startdt, c.enddt] | |||
c = Redmine::Helpers::Calendar.new(Date.today, :en, :week) | |||
assert_equal [7, 6], [c.startdt.cwday, c.enddt.cwday] | |||
end | |||
end |