Browse Source

Calendar:

* 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-8f06a7374b81
tags/0.6.0
Jean-Philippe Lang 16 years ago
parent
commit
ec51cdd0f9

+ 2
- 0
app/controllers/my_controller.rb View File

@@ -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


+ 7
- 15
app/controllers/projects_controller.rb View File

@@ -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

+ 36
- 0
app/views/common/_calendar.rhtml View File

@@ -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>

+ 5
- 44
app/views/my/blocks/_calendar.rhtml View File

@@ -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 } %>

+ 1
- 49
app/views/projects/calendar.rhtml View File

@@ -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' %>&nbsp;&nbsp;<%= l(:text_tip_task_begin_day) %><br />
<%= image_tag 'arrow_to.png' %>&nbsp;&nbsp;<%= l(:text_tip_task_end_day) %><br />

+ 1
- 0
lang/bg.yml View File

@@ -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: Невалиден потребител или парола.

+ 1
- 0
lang/cs.yml View File

@@ -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

+ 1
- 0
lang/de.yml View File

@@ -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

+ 1
- 0
lang/en.yml View File

@@ -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

+ 1
- 0
lang/es.yml View File

@@ -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

+ 1
- 0
lang/fr.yml View File

@@ -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.

+ 1
- 0
lang/it.yml View File

@@ -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.

+ 1
- 0
lang/ja.yml View File

@@ -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: ユーザ名もしくはパスワードが無効

+ 1
- 0
lang/nl.yml View File

@@ -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

+ 1
- 0
lang/pl.yml View File

@@ -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

+ 1
- 0
lang/pt-br.yml View File

@@ -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.

+ 1
- 0
lang/pt.yml View File

@@ -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.

+ 1
- 0
lang/ro.yml View File

@@ -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.

+ 1
- 0
lang/sv.yml View File

@@ -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

+ 1
- 0
lang/zh.yml View File

@@ -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: 用户名或密码不正确

+ 76
- 0
lib/redmine/helpers/calendar.rb View File

@@ -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

+ 6
- 1
public/stylesheets/application.css View File

@@ -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;}

+ 43
- 0
test/unit/calendar_test.rb View File

@@ -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

Loading…
Cancel
Save