Sfoglia il codice sorgente

Display calendar in vertical list layout on mobile screens (#33682).

Patch by Takashi Kato.


git-svn-id: https://svn.redmine.org/redmine/trunk@22283 e93f8b46-1217-0410-a6f0-8f06a7374b81
tags/5.1.0
Go MAEDA 8 mesi fa
parent
commit
4e0bb4990c

+ 0
- 1
app/controllers/my_controller.rb Vedi File

@@ -33,7 +33,6 @@ class MyController < ApplicationController
helper :custom_fields
helper :queries
helper :activities
helper :calendars

def index
page

+ 0
- 29
app/helpers/calendars_helper.rb Vedi File

@@ -1,29 +0,0 @@
# frozen_string_literal: true

# Redmine - project management software
# Copyright (C) 2006-2023 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 CalendarsHelper
include Redmine::Utils::DateCalculation

def calendar_day_css_classes(calendar, day)
css = day.month==calendar.month ? +'even' : +'odd'
css << " today" if User.current.today == day
css << " nwday" if non_working_week_days.include?(day.cwday)
css
end
end

+ 31
- 42
app/views/common/_calendar.html.erb Vedi File

@@ -1,48 +1,37 @@
<%= form_tag({}, :data => {:cm_url => issues_context_menu_path}) do -%>
<%= hidden_field_tag 'back_url', url_for(:params => request.query_parameters), :id => nil %>
<table class="cal">
<thead>
<tr>
<th scope="col" title="<%= l(:label_week) %>" class="week-number"></th>
<% 7.times do |i| %>
<th scope="col"><%= day_name((calendar.first_wday + i) % 7) %></th>
<% end %>
</tr>
</thead>
<tbody>
<tr>
<% day = calendar.startdt %>
<% while day <= calendar.enddt %>
<% if day.cwday == calendar.first_wday %>
<td class='week-number' title='<%= l(:label_week) %>'>
<%= (day + (11 - day.cwday) % 7).cweek %>
</td>
<ul class="cal">
<li scope="col" title="<%= l(:label_week) %>" class="calhead week-number"></li>
<% 7.times do |i| %>
<li scope="col" class="calhead"><%= day_name((calendar.first_wday + i) % 7) %></li>
<% end %>
<td class="<%= calendar_day_css_classes(calendar, day) %>">
<p class="day-num"><%= day.day %></p>
<% calendar.events_on(day).each do |i| %>
<% if i.is_a? Issue %>
<div class="<%= i.css_classes %> <%= 'starting' if day == i.start_date %> <%= 'ending' if day == i.due_date %> tooltip hascontextmenu">
<%= "#{i.project} -" unless @project && @project == i.project %>
<%= link_to_issue i, :truncate => 30 %>
<span class="tip"><%= render_issue_tooltip i %></span>
<%= check_box_tag 'ids[]', i.id, false, :style => 'display:none;', :id => nil %>
</div>
<% else %>
<span class="icon icon-package">
<%= "#{i.project} -" unless @project && @project == i.project %>
<%= link_to_version i %>
</span>
<% calendar.format_month.each_slice(7) do |week| %>
<li class='week-number'>
<span class="label-week"><%= l(:label_week) %></span> <%= calendar.week_number week.first %>
</li>
<% week.each do |day| %>
<li class="<%= calendar.day_css_classes day %> calbody">
<p class="day-num"><%= day.day %>
<span class="abbr-day">(<%= abbr_day_name(day.cwday) %>)</span>
</p>
<% calendar.events_on(day).each do |i| %>
<% if i.is_a? Issue %>
<%= tag.div class: [ i.css_classes, 'tooltip hascontextmenu', starting: day == i.start_date, ending: day == i.due_date] do %>
<%= "#{i.project} -" unless @project && @project == i.project %>
<%= link_to_issue i, :truncate => 30 %>
<span class="tip"><%= render_issue_tooltip i %></span>
<%= check_box_tag 'ids[]', i.id, false, :style => 'display:none;', :id => nil %>
<% end %>
<% else %>
<span class="icon icon-package">
<%= "#{i.project} -" unless @project && @project == i.project %>
<%= link_to_version i %>
</span>
<% end %>
<% end %>
</li>
<% end %>
<% end %>
<% end %>
</td>
<% if day.cwday==calendar.last_wday and day!=calendar.enddt %>
</tr><tr>
<% end %>
<% day = day + 1 %>
<% end %>
</tr>
</tbody>
</table>
</ul>
<% end %>
<%= context_menu %>

+ 17
- 0
lib/redmine/helpers/calendar.rb Vedi File

@@ -23,6 +23,8 @@ module Redmine
# Simple class to compute the start and end dates of a calendar
class Calendar
include Redmine::I18n
include Redmine::Utils::DateCalculation

attr_reader :startdt, :enddt

def initialize(date, lang = current_language, period = :month)
@@ -47,6 +49,21 @@ module Redmine
end
end

def format_month
(@startdt..@enddt).to_a
end

def week_number(day)
(day + (11 - day.cwday) % 7).cweek
end

def day_css_classes(day)
css = day.month==month ? +'even' : +'odd'
css << " today" if User.current.today == day
css << " nwday" if non_working_week_days.include?(day.cwday)
css
end

# Sets calendar events
def events=(events)
@events = events

+ 4
- 0
lib/redmine/i18n.rb Vedi File

@@ -103,6 +103,10 @@ module Redmine
::I18n.t('date.day_names')[day % 7]
end

def abbr_day_name(day)
::I18n.t('date.abbr_day_names')[day % 7]
end

def day_letter(day)
::I18n.t('date.abbr_day_names')[day % 7].first
end

+ 54
- 15
public/stylesheets/application.css Vedi File

@@ -1100,21 +1100,60 @@ vertical-align: bottom;
}

/***** Calendar *****/
table.cal {width: 100%; margin: 0 0 6px 0; border: 1px solid #c0c0c0; border-spacing: 0; border-radius: 3px;}
table.cal thead th {width: 14%; background-color:#EEEEEE; padding: 4px; }
table.cal thead th.week-number {width: auto;}
table.cal tbody tr {height: 100px;}
table.cal td .icon {padding-top: 2px; padding-bottom: 3px;}
table.cal td {border: 1px solid #d7d7d7; vertical-align: top; font-size: 0.9em; border-bottom: 0; border-right: 0;}
table.cal td.week-number { background-color:#EEEEEE; padding: 4px; border:none; font-size: 1em;}
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;}
table.cal td.nwday:not(.odd) {background-color:#f1f1f1;}
table.cal .starting a.issue, p.cal.legend .starting {background: url(../images/bullet_go.png) no-repeat -1px -2px; padding-left:16px;}
table.cal .ending a.issue, p.cal.legend .ending {background: url(../images/bullet_end.png) no-repeat -1px -2px; padding-left:16px;}
table.cal .starting.ending a.issue, p.cal.legend .starting.ending {background: url(../images/bullet_diamond.png) no-repeat -1px -2px; padding-left:16px;}
ul.cal {
list-style: none;
width: 100%;
padding: 0;
display: grid;
grid-template-columns: 2rem repeat(7, 1fr);
margin: 0;
border: 1px solid #c0c0c0;
border-spacing: 0;
border-radius: 3px;
}

.cal .calhead {
background-color:#eee;
text-align: center;
font-weight: bold;
padding: 4px
}

.cal .week-number {
background-color:#eee;
border:none;
font-size: 1em;
padding: 4px;
text-align: center;
}

.cal .week-number .label-week {
display: none;
}

.cal .calbody {
border: 1px solid #d7d7d7;
vertical-align: top;
font-size: 0.9em;
border-bottom: 0;
border-right: 0;
line-height: 1.2;
min-height: calc(1.2em * 6);
padding: 2px;
}

.cal .calbody p.day-num {font-size: 1.1em; text-align:right;}
.cal .calbody .abbr-day {display:none}
.cal .calbody.odd p.day-num {color: #bbb;}
.cal .calbody.today {background:#ffd;}
.cal .calbody.today p.day-num {font-weight: bold;}

.cal .calbody .icon {padding-top: 2px; padding-bottom: 3px;}
.cal .calbody.nwday:not(.odd) {background-color:#f1f1f1;}
.cal .starting a.issue, p.cal.legend .starting {background: url(../images/bullet_go.png) no-repeat -1px -2px; padding-left:16px;}
.cal .ending a.issue, p.cal.legend .ending {background: url(../images/bullet_end.png) no-repeat -1px -2px; padding-left:16px;}
.cal .starting.ending a.issue, p.cal.legend .starting.ending {background: url(../images/bullet_diamond.png) no-repeat -1px -2px; padding-left:16px;}

p.cal.legend span {display:block;}
.controller-calendars p.buttons {margin-top: unset;}


+ 32
- 0
public/stylesheets/responsive.css Vedi File

@@ -819,6 +819,38 @@
margin-left: 0;
width: 100%;
}

/* Calendar */
ul.cal {
display: block
}
.cal .calhead {
display: none
}

.cal .calbody {
min-height: calc(1.2em * 3);
}

.cal .calbody .abbr-day {
display: inline;
}

.cal .week-number {
border: 1px solid #c0c0c0;
text-align: left;
font-weight: bold;
background-color: #def;
}

.cal .week-number .label-week {
display: inline;
}

.cal .calbody p.day-num {
font-size: 1.1em;
text-align: left;
}
}

@media all and (max-width: 599px) {

+ 76
- 88
test/functional/calendars_controller_test.rb Vedi File

@@ -65,19 +65,17 @@ class CalendarsControllerTest < Redmine::ControllerTest
# Assert context menu on issues
assert_select 'form[data-cm-url=?]', '/issues/context_menu'

assert_select 'table.cal' do
assert_select 'tr' do
assert_select 'td' do
assert_select(
'div.issue.hascontextmenu.tooltip.starting',
:text => /Add ingredients categories/
) do
assert_select 'a.issue[href=?]', '/issues/2', :text => 'Feature request #2'
assert_select 'span.tip' do
assert_select 'img[class="gravatar"]'
end
assert_select 'input[name=?][type=?][value=?]', 'ids[]', 'checkbox', '2'
assert_select 'ul.cal' do
assert_select 'li' do
assert_select(
'div.issue.hascontextmenu.tooltip.starting',
:text => /Add ingredients categories/
) do
assert_select 'a.issue[href=?]', '/issues/2', :text => 'Feature request #2'
assert_select 'span.tip' do
assert_select 'img[class="gravatar"]'
end
assert_select 'input[name=?][type=?][value=?]', 'ids[]', 'checkbox', '2'
end
end
end
@@ -89,16 +87,14 @@ class CalendarsControllerTest < Redmine::ControllerTest
get(:show, :params => {:project_id => 1})
assert_response :success

assert_select 'table.cal' do
assert_select 'tr' do
assert_select 'td' do
assert_select(
'div.issue.hascontextmenu.tooltip.ending',
:text => /Cannot print recipes/
) do
assert_select 'a.issue[href=?]', '/issues/1', :text => 'Bug #1'
assert_select 'input[name=?][type=?][value=?]', 'ids[]', 'checkbox', '1'
end
assert_select 'ul.cal' do
assert_select 'li' do
assert_select(
'div.issue.hascontextmenu.tooltip.ending',
:text => /Cannot print recipes/
) do
assert_select 'a.issue[href=?]', '/issues/1', :text => 'Bug #1'
assert_select 'input[name=?][type=?][value=?]', 'ids[]', 'checkbox', '1'
end
end
end
@@ -120,24 +116,22 @@ class CalendarsControllerTest < Redmine::ControllerTest
)
assert_response :success

assert_select 'table.cal' do
assert_select 'tr' do
assert_select 'td' do
assert_select 'ul.cal' do
assert_select 'li' do
assert_select(
'div.issue.hascontextmenu.tooltip.starting.ending',
:text => /#{subject}/
) do
assert_select(
'div.issue.hascontextmenu.tooltip.starting.ending',
:text => /#{subject}/
) do
assert_select(
'a.issue[href=?]', "/issues/#{issue.id}",
:text => "Bug ##{issue.id}"
)
assert_select(
'input[name=?][type=?][value=?]',
'ids[]',
'checkbox',
issue.id.to_s
)
end
'a.issue[href=?]', "/issues/#{issue.id}",
:text => "Bug ##{issue.id}"
)
assert_select(
'input[name=?][type=?][value=?]',
'ids[]',
'checkbox',
issue.id.to_s
)
end
end
end
@@ -149,14 +143,12 @@ class CalendarsControllerTest < Redmine::ControllerTest
get(:show, :params => {:project_id => 1})
assert_response :success

assert_select 'table.cal' do
assert_select 'tr' do
assert_select 'td' do
assert_select(
'span.icon.icon-package'
) do
assert_select 'a[href=?]', '/versions/2', :text => '1.0'
end
assert_select 'ul.cal' do
assert_select 'li' do
assert_select(
'span.icon.icon-package'
) do
assert_select 'a[href=?]', '/versions/2', :text => '1.0'
end
end
end
@@ -179,16 +171,14 @@ class CalendarsControllerTest < Redmine::ControllerTest
get :show
assert_response :success

assert_select 'table.cal' do
assert_select 'tr' do
assert_select 'td' do
assert_select(
'div.issue.hascontextmenu.tooltip.starting',
:text => /eCookbook.*Add ingredients categories/m
) do
assert_select 'a.issue[href=?]', '/issues/2', :text => 'Feature request #2'
assert_select 'input[name=?][type=?][value=?]', 'ids[]', 'checkbox', '2'
end
assert_select 'ul.cal' do
assert_select 'li' do
assert_select(
'div.issue.hascontextmenu.tooltip.starting',
:text => /eCookbook.*Add ingredients categories/m
) do
assert_select 'a.issue[href=?]', '/issues/2', :text => 'Feature request #2'
assert_select 'input[name=?][type=?][value=?]', 'ids[]', 'checkbox', '2'
end
end
end
@@ -200,17 +190,15 @@ class CalendarsControllerTest < Redmine::ControllerTest
get :show
assert_response :success

assert_select 'table.cal' do
assert_select 'tr' do
assert_select 'td' do
assert_select 'ul.cal' do
assert_select 'li' do
assert_select(
'span.icon.icon-package'
) do
assert_select(
'span.icon.icon-package'
) do
assert_select(
'a[href=?]', '/versions/2',
:text => 'eCookbook - 1.0'
)
end
'a[href=?]', '/versions/2',
:text => 'eCookbook - 1.0'
)
end
end
end
@@ -228,16 +216,16 @@ class CalendarsControllerTest < Redmine::ControllerTest
assert_response :success
end

assert_select 'tr' do
assert_select 'td.week-number', :text => '53'
assert_select 'td.odd', :text => '27'
assert_select 'td.even', :text => '2'
assert_select 'ul' do
assert_select 'li.week-number:nth-of-type(2)', :text => /53$/
assert_select 'li.odd', :text => /^27/
assert_select 'li.even', :text => /^2/
end

assert_select 'tr' do
assert_select 'td.week-number', :text => '1'
assert_select 'td.odd', :text => '3'
assert_select 'td.even', :text => '9'
assert_select 'ul' do
assert_select 'li.week-number', :text => /1$/
assert_select 'li.odd', :text => /^3/
assert_select 'li.even', :text => /^9/
end

with_settings :start_of_week => 1 do
@@ -251,16 +239,16 @@ class CalendarsControllerTest < Redmine::ControllerTest
assert_response :success
end

assert_select 'tr' do
assert_select 'td.week-number', :text => '53'
assert_select 'td.even', :text => '28'
assert_select 'td.even', :text => '3'
assert_select 'ul' do
assert_select 'li.week-number:nth-of-type(2)', :text => /53$/
assert_select 'li.even', :text => /^28/
assert_select 'li.even', :text => /^3/
end

assert_select 'tr' do
assert_select 'td.week-number', :text => '1'
assert_select 'td.even', :text => '4'
assert_select 'td.even', :text => '10'
assert_select 'ul' do
assert_select 'li.week-number', :text => /1$/
assert_select 'li.even', :text => /^4/
assert_select 'li.even', :text => /^10/
end
end

@@ -296,12 +284,12 @@ class CalendarsControllerTest < Redmine::ControllerTest
)
assert_response :success

assert_select 'tr:nth-child(2)' do
assert_select 'td.week-number', :text => '49'
assert_select 'ul' do
assert_select 'li.week-number:nth-of-type(2)', :text => /48$/
# non working days should have "nwday" CSS class
assert_select 'td.nwday', 2
assert_select 'td.nwday', :text => '4'
assert_select 'td.nwday', :text => '10'
assert_select 'li.nwday', 10
assert_select 'li.nwday', :text => /^4/
assert_select 'li.nwday', :text => /^10/
end
end
end

+ 15
- 17
test/functional/my_controller_test.rb Vedi File

@@ -444,24 +444,22 @@ class MyControllerTest < Redmine::ControllerTest

assert_select 'form[data-cm-url=?]', '/issues/context_menu'

assert_select 'table.cal' do
assert_select 'tr' do
assert_select 'td' do
assert_select 'ul.cal' do
assert_select 'li' do
assert_select(
'div.issue.hascontextmenu.tooltip.starting.ending',
:text => /eCookbook.*#{subject}/m
) do
assert_select(
'a.issue[href=?]', "/issues/#{issue.id}",
:text => "Bug ##{issue.id}"
)
assert_select(
'div.issue.hascontextmenu.tooltip.starting.ending',
:text => /eCookbook.*#{subject}/m
) do
assert_select(
'a.issue[href=?]', "/issues/#{issue.id}",
:text => "Bug ##{issue.id}"
)
assert_select(
'input[name=?][type=?][value=?]',
'ids[]',
'checkbox',
issue.id.to_s
)
end
'input[name=?][type=?][value=?]',
'ids[]',
'checkbox',
issue.id.to_s
)
end
end
end

Loading…
Annulla
Salva