Merge branch 'feature.issue-due-date' of https://github.com/treffynnon/Indefero into develop

This commit is contained in:
Thomas Keller 2012-05-06 23:12:52 +02:00
commit e0dec2278c
40 changed files with 884 additions and 31 deletions

View File

@ -1,6 +1,10 @@
# InDefero 1.3.2 - xxx xxx xx xx:xx 2012 UTC
# InDefero 1.4 - xxx xxx xx xx:xx 2012 UTC
- ...
## New Features
- Indefero can now record the due date of an issue and lets
you filter and search by overdue issues (fixes issue 584,
thanks to Simon Holywell!)
# InDefero 1.3.1 - Sun May 06 20:32 2012 UTC

View File

@ -112,6 +112,12 @@ class IDF_Form_IssueCreate extends Pluf_Form
'size' => 15,
),
));
$this->fields['due_dtime'] = new Pluf_Form_Field_Date(
array('required' => false,
'label' => __('Due date'),
'initial' => '',
'widget_attrs' => array('size' => 15,),
));
$this->fields['relation_type0'] = new Pluf_Form_Field_Varchar(
array('required' => false,
@ -368,6 +374,7 @@ class IDF_Form_IssueCreate extends Pluf_Form
$issue->status = new IDF_Tag($_t[0]); // first one is the default
$issue->owner = null;
}
$issue->due_dtime = $this->cleaned_data['due_dtime'];
$issue->summary = trim($this->cleaned_data['summary']);
$issue->create();
foreach ($tags as $tag) {

View File

@ -103,6 +103,13 @@ class IDF_Form_IssueUpdate extends IDF_Form_IssueCreate
'size' => 15,
),
));
$due_dtime = substr($this->issue->due_dtime, 0, 10);
$this->fields['due_dtime'] = new Pluf_Form_Field_Date(
array('required' => false,
'label' => __('Due date'),
'initial' => $due_dtime,
'widget_attrs' => array('size' => 15,),
));
$idx = 0;
// note: clean_relation_type0 and clean_relation_issue0 already
@ -266,6 +273,9 @@ class IDF_Form_IssueUpdate extends IDF_Form_IssueCreate
or ((!is_null($owner) and !is_null($this->issue->get_owner())) and $owner->id != $this->issue->get_owner()->id)) {
return $this->cleaned_data;
}
if (trim($this->issue->due_dtime) != trim($this->cleaned_data['due_dtime'])) {
return $this->cleaned_data;
}
$tags = array();
for ($i=1;$i<7;$i++) {
if (strlen($this->cleaned_data['label'.$i]) > 0) {
@ -385,6 +395,9 @@ class IDF_Form_IssueUpdate extends IDF_Form_IssueCreate
or ((!is_null($owner) and !is_null($this->issue->get_owner())) and $owner->id != $this->issue->get_owner()->id)) {
$changes['ow'] = (is_null($owner)) ? '---' : $owner->login;
}
if (trim($this->issue->due_dtime) != trim($this->cleaned_data['due_dtime'])) {
$changes['du'] = Pluf_Template_dateFormat($this->cleaned_data['due_dtime']);
}
// Issue relations - additions
foreach ($this->cleaned_data['_added_issue_relations'] as $verb => $ids) {
$other_verb = $this->relation_types[$verb];
@ -431,6 +444,7 @@ class IDF_Form_IssueUpdate extends IDF_Form_IssueCreate
$this->issue->summary = trim($this->cleaned_data['summary']);
$this->issue->status = $status;
$this->issue->owner = $owner;
$this->issue->due_dtime = $this->cleaned_data['due_dtime'];
}
// Create the comment
$comment = new IDF_IssueComment();

View File

@ -91,6 +91,13 @@ class IDF_Issue extends Pluf_Model
'model' => 'IDF_Tag',
'verbose' => __('labels'),
),
'due_dtime' =>
array(
'type' => 'Pluf_DB_Field_Datetime',
'blank' => true,
'is_null' => true,
'verbose' => __('due date'),
),
'status' =>
array(
'type' => 'Pluf_DB_Field_Foreignkey',
@ -149,11 +156,28 @@ class IDF_Issue extends Pluf_Model
IDF_Search::remove($this);
}
function restore()
{
// Note: If a due date has not been set then it should
// be set to null and not a useless/confusing date so...
if ('0000-00-00 00:00:00' === $this->due_dtime) {
$this->due_dtime = null;
}
}
function preSave($create=false)
{
if ($this->id == '') {
$this->creation_dtime = gmdate('Y-m-d H:i:s');
}
// Note: If a due date is supplied then it must have
// a time appended to it so that calculations of when
// an issue falls overdue are accurate. In this case
// 23:59:59 is added to signify the end of the day.
if ($this->due_dtime and !empty($this->due_dtime)) {
$this->due_dtime = date('Y-m-d 23:59:59',
strtotime($this->due_dtime));
}
$this->modif_dtime = gmdate('Y-m-d H:i:s');
}

View File

@ -153,6 +153,8 @@ class IDF_IssueComment extends Pluf_Model
$out .= __('Status:'); break;
case 'ow':
$out .= __('Owner:'); break;
case 'du':
$out .= __('Due date:'); break;
case 'lb':
$out .= __('Labels:'); break;
case 'rel':

View File

@ -0,0 +1,55 @@
<?php
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
# ***** BEGIN LICENSE BLOCK *****
# This file is part of InDefero, an open source project management application.
# Copyright (C) 2008-2011 Céondo Ltd and contributors.
#
# InDefero 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.
#
# InDefero 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 St, Fifth Floor, Boston, MA 02110-1301 USA
#
# ***** END LICENSE BLOCK ***** */
/**
* Add the private column for the project.
*/
function IDF_Migrations_26IssueDueDate_up($params=null)
{
$table = Pluf::factory('IDF_Issue')->getSqlTable();
$sql = array();
$sql['PostgreSQL'] = 'ALTER TABLE '.$table.' ADD COLUMN "due_dtime" TIMESTAMP';
$sql['MySQL'] = 'ALTER TABLE '.$table.' ADD COLUMN `due_dtime` DATETIME';
$db = Pluf::db();
$engine = Pluf::f('db_engine');
if (!isset($sql[$engine])) {
throw new Exception('SQLite complex migration not supported.');
}
$db->execute($sql[$engine]);
}
function IDF_Migrations_26IssueDueDate_down($params=null)
{
$table = Pluf::factory('IDF_Issue')->getSqlTable();
$sql = array();
$sql['PostgreSQL'] = 'ALTER TABLE '.$table.' DROP COLUMN "due_dtime"';
$sql['MySQL'] = 'ALTER TABLE '.$table.' DROP COLUMN `due_dtime`';
$db = Pluf::db();
$engine = Pluf::f('db_engine');
if (!isset($sql[$engine])) {
throw new Exception('SQLite complex migration not supported.');
}
$db->execute($sql[$engine]);
}

View File

@ -201,6 +201,39 @@ GROUP BY uid";
return $ownerStatistics;
}
/**
* Returns the number of overdue issues.
*
* @return int Count
*/
public function getIssueCountByDueDate($due='overdue', $label=null, $ids=array())
{
$tags = array();
foreach ($this->getTagsFromConfig('labels_issue_open', IDF_Form_IssueTrackingConf::init_open, 'Status') as $tag) {
$tags[] = (int)$tag->id;
}
if (count($tags) == 0) return array();
$sql = new Pluf_SQL(sprintf('project=%%s AND status IN (%s)', implode(', ', $tags)), array($this->id));
if (!is_null($label)) {
$sql2 = new Pluf_SQL('idf_tag_id=%s', array($label->id));
$sql->SAnd($sql2);
}
if (count($ids) > 0) {
$sql2 = new Pluf_SQL(sprintf('id IN (%s)', implode(', ', $ids)));
$sql->SAnd($sql2);
}
if('overdue' === $due) {
$sql3 = new Pluf_SQL('due_dtime < NOW()');
} else {
$sql3 = new Pluf_SQL('due_dtime >= NOW()');
}
$sql->SAnd($sql3);
$params = array('filter' => $sql->gen());
if (!is_null($label)) { $params['view'] = 'join_tags'; }
$gissue = new IDF_Issue();
return $gissue->getCount($params);
}
/**
* Returns the number of open/closed issues.
*

View File

@ -42,6 +42,7 @@ class IDF_Views_Issue
// Get stats about the issues
$open = $prj->getIssueCountByStatus('open');
$closed = $prj->getIssueCountByStatus('closed');
$overdue = $prj->getIssueCountByDueDate();
// Paginator to paginate the issues
$pag = new Pluf_Paginator(new IDF_Issue());
$pag->class = 'recent-issues';
@ -61,9 +62,10 @@ class IDF_Views_Issue
'id' => __('Id'),
array('summary', 'IDF_Views_Issue_SummaryAndLabels', __('Summary')),
array('status', 'IDF_Views_Issue_ShowStatus', __('Status')),
array('due_dtime', 'IDF_Views_Issue_DueDate', __('Due Date')),
array('modif_dtime', 'Pluf_Paginator_DateAgo', __('Last Updated')),
);
$pag->configure($list_display, array(), array('id', 'status', 'modif_dtime'));
$pag->configure($list_display, array(), array('id', 'status', 'due_dtime', 'modif_dtime'));
$pag->items_per_page = 10;
$pag->no_results_text = __('No issues were found.');
$pag->setFromRequest($request);
@ -71,6 +73,7 @@ class IDF_Views_Issue
'page_title' => $title,
'open' => $open,
'closed' => $closed,
'overdue' => $overdue,
'issues' => $pag,
'cloud' => 'issues',
);
@ -88,6 +91,7 @@ class IDF_Views_Issue
{
$tagStatistics = array();
$ownerStatistics = array();
$duedateStatistics = array();
$status = array();
$isTrackerEmpty = false;
@ -121,6 +125,14 @@ class IDF_Views_Issue
}
arsort($ownerStatistics);
// Issue due date statistics
$overdue = $prj->getIssueCountByDueDate();
$combined_opened = $overdue + $opened;
$duedateStatistics = array();
if ($combined_opened > 0) {
$duedateStatistics = array($overdue, (int)(100 * $overdue / $combined_opened));
}
// Issue class tag statistics
$grouped_tags = $prj->getTagCloud();
foreach ($grouped_tags as $class => $tags) {
@ -154,6 +166,7 @@ class IDF_Views_Issue
'project' => $prj,
'tagStatistics' => $tagStatistics,
'ownerStatistics' => $ownerStatistics,
'duedateStatistics' => $duedateStatistics,
'status' => $status,
),
$request);
@ -187,9 +200,16 @@ class IDF_Views_Issue
$nb_open = Pluf::factory('IDF_Issue')->getCount(array('filter'=>$sql->gen()));
$sql = new Pluf_SQL('project=%s AND id IN ('.$issue_ids.') AND status IN ('.implode(', ', $ctags).')', array($prj->id));
$nb_closed = Pluf::factory('IDF_Issue')->getCount(array('filter'=>$sql->gen()));
$sql = new Pluf_SQL('project=%s AND id IN ('.$issue_ids.') AND status IN ('.implode(', ', $otags).') AND due_dtime < NOW()', array($prj->id));
$nb_overdue = Pluf::factory('IDF_Issue')->getCount(array('filter'=>$sql->gen()));
// Generate a filter for the paginator
switch ($match[2]) {
case 'overdue':
$title = sprintf(__('Watch List: Overdue Issues for %s'), (string) $prj);
$summary = __('This table shows the overdue issues in your watch list for %s project.', (string) $prj);
$f_sql = new Pluf_SQL('project=%s AND id IN ('.$issue_ids.') AND status IN ('.implode(', ', $otags).') AND due_dtime < NOW()', array($prj->id));
break;
case 'closed':
$title = sprintf(__('Watch List: Closed Issues for %s'), (string) $prj);
$summary = __('This table shows the closed issues in your watch list for %s project.', (string) $prj);
@ -220,9 +240,10 @@ class IDF_Views_Issue
'id' => __('Id'),
array('summary', 'IDF_Views_Issue_SummaryAndLabels', __('Summary')),
array('status', 'IDF_Views_Issue_ShowStatus', __('Status')),
array('due_dtime', 'IDF_Views_Issue_DueDate', __('Due Date')),
array('modif_dtime', 'Pluf_Paginator_DateAgo', __('Last Updated')),
);
$pag->configure($list_display, array(), array('id', 'status', 'modif_dtime'));
$pag->configure($list_display, array(), array('id', 'status', 'due_dtime', 'modif_dtime'));
$pag->items_per_page = 10;
$pag->no_results_text = __('No issues were found.');
$pag->setFromRequest($request);
@ -231,6 +252,7 @@ class IDF_Views_Issue
'page_title' => $title,
'open' => $nb_open,
'closed' => $nb_closed,
'overdue' => $nb_overdue,
'issues' => $pag,
),
$request);
@ -270,9 +292,16 @@ class IDF_Views_Issue
$nb_open = Pluf::factory('IDF_Issue')->getCount(array('filter'=>$sql->gen()));
$sql = new Pluf_SQL('id IN ('.$issue_ids.') AND status IN ('.implode(', ', $ctags).')', array());
$nb_closed = Pluf::factory('IDF_Issue')->getCount(array('filter'=>$sql->gen()));
$sql = new Pluf_SQL('id IN ('.$issue_ids.') AND status IN ('.implode(', ', $otags).') AND due_dtime < NOW()', array());
$nb_overdue = Pluf::factory('IDF_Issue')->getCount(array('filter'=>$sql->gen()));
// Generate a filter for the paginator
switch ($match[1]) {
case 'overdue':
$title = sprintf(__('Watch List: Overdue Issues'));
$summary = __('This table shows the overdue issues in your watch list.');
$f_sql = new Pluf_SQL('id IN ('.$issue_ids.') AND status IN ('.implode(', ', $otags).') AND due_dtime < NOW()', array());
break;
case 'closed':
$title = sprintf(__('Watch List: Closed Issues'));
$summary = __('This table shows the closed issues in your watch list.');
@ -302,9 +331,10 @@ class IDF_Views_Issue
array('summary', 'IDF_Views_Issue_SummaryAndLabelsUnknownProject', __('Summary')),
array('project', 'Pluf_Paginator_FkToString', __('Project')),
array('status', 'IDF_Views_Issue_ShowStatus', __('Status')),
array('due_dtime', 'IDF_Views_Issue_DueDate', __('Due Date')),
array('modif_dtime', 'Pluf_Paginator_DateAgo', __('Last Updated')),
);
$pag->configure($list_display, array(), array('id', 'project', 'status', 'modif_dtime'));
$pag->configure($list_display, array(), array('id', 'project', 'status', 'due_dtime', 'modif_dtime'));
$pag->items_per_page = 10;
$pag->no_results_text = __('No issues were found.');
$pag->setFromRequest($request);
@ -312,6 +342,7 @@ class IDF_Views_Issue
array('page_title' => $title,
'open' => $nb_open,
'closed' => $nb_closed,
'overdue' => $nb_overdue,
'issues' => $pag,
),
$request);
@ -390,9 +421,10 @@ class IDF_Views_Issue
'id' => __('Id'),
array('summary', 'IDF_Views_Issue_SummaryAndLabels', __('Summary')),
array('status', 'IDF_Views_Issue_ShowStatus', __('Status')),
array('due_dtime', 'IDF_Views_Issue_DueDate', __('Due Date')),
array('modif_dtime', 'Pluf_Paginator_DateAgo', __('Last Updated')),
);
$pag->configure($list_display, array(), array('id', 'status', 'modif_dtime'));
$pag->configure($list_display, array(), array('id', 'status', 'due_dtime', 'modif_dtime'));
$pag->items_per_page = 10;
$pag->no_results_text = __('No issues were found.');
$pag->setFromRequest($request);
@ -443,6 +475,7 @@ class IDF_Views_Issue
'preview' => $preview,
'issue' => new IDF_Issue(),
),
self::getDateShortcuts(),
self::autoCompleteArrays($prj)
);
if ($api == true) return $params;
@ -461,7 +494,7 @@ class IDF_Views_Issue
public function searchStatus($request, $match)
{
$query = !isset($request->REQUEST['q']) ? '' : $request->REQUEST['q'];
$status = in_array($match[2], array('open', 'closed')) ? $match[2] : 'open';
$status = in_array($match[2], array('open', 'closed', 'overdue')) ? $match[2] : 'open';
return $this->doSearch($request, $query, $status);
}
@ -470,7 +503,7 @@ class IDF_Views_Issue
{
$query = !isset($request->REQUEST['q']) ? '' : $request->REQUEST['q'];
$tag_id = intval($match[2]);
$status = in_array($match[3], array('open', 'closed')) ? $match[3] : 'open';
$status = in_array($match[3], array('open', 'closed', 'overdue')) ? $match[3] : 'open';
return $this->doSearch($request, $query, $status, $tag_id);
}
@ -490,6 +523,10 @@ class IDF_Views_Issue
$title = sprintf(__('Search issues - %s'), $query);
if ($status === 'closed') {
$title = sprintf(__('Search closed issues - %s'), $query);
} elseif ($status === 'overdue') {
$title = sprintf(__('Search overdue issues - %s'), $query);
$status = 'open';
$overdue_status = true;
}
// using Plufs ResultSet implementation here is inefficient, because
@ -510,6 +547,10 @@ class IDF_Views_Issue
'AND status IN ('.implode(', ', $otags).') '.
($tag_id !== null ? 'AND idf_tag_id='.$tag_id.' ' : '')
);
if (isset($overdue_status)) {
$sql2 = new Pluf_SQL('due_dtime < NOW()');
$sql->SAnd($sql2);
}
$model = new IDF_Issue();
$issues = $model->getList(array('filter' => $sql->gen(), 'view' => 'join_tags'));
@ -542,6 +583,7 @@ class IDF_Views_Issue
'id' => __('Id'),
array('summary', 'IDF_Views_Issue_SummaryAndLabels', __('Summary')),
array('status', 'IDF_Views_Issue_ShowStatus', __('Status')),
array('due_dtime', 'IDF_Views_Issue_DueDate', __('Due Date')),
array('modif_dtime', 'Pluf_Paginator_DateAgo', __('Last Updated')),
));
// disable paginating
@ -562,6 +604,7 @@ class IDF_Views_Issue
}
// get stats about the issues
$overdue = $prj->getIssueCountByDueDate('overdue', $tag, $issue_ids);
$open = $prj->getIssueCountByStatus('open', $tag, $issue_ids);
$closed = $prj->getIssueCountByStatus('closed', $tag, $issue_ids);
@ -583,6 +626,7 @@ class IDF_Views_Issue
'status' => $status,
'open' => $open,
'closed' => $closed,
'overdue' => $overdue,
'tag' => $tag,
'all_tags' => $grouped_tags,
);
@ -669,6 +713,7 @@ class IDF_Views_Issue
'next_issue_id' => $next_issue_id,
'related_issues' => $related_issues,
),
self::getDateShortcuts(),
$arrays),
$request);
}
@ -746,6 +791,7 @@ class IDF_Views_Issue
// Get stats about the issues
$open = $prj->getIssueCountByStatus('open');
$closed = $prj->getIssueCountByStatus('closed');
$overdue = $prj->getIssueCountByDueDate();
// Paginator to paginate the issues
$pag = new Pluf_Paginator(new IDF_Issue());
$pag->class = 'recent-issues';
@ -765,9 +811,10 @@ class IDF_Views_Issue
'id' => __('Id'),
array('summary', 'IDF_Views_Issue_SummaryAndLabels', __('Summary')),
array('status', 'IDF_Views_Issue_ShowStatus', __('Status')),
array('due_dtime', 'IDF_Views_Issue_DueDate', __('Due Date')),
array('modif_dtime', 'Pluf_Paginator_DateAgo', __('Last Updated')),
);
$pag->configure($list_display, array(), array('id', 'status', 'modif_dtime'));
$pag->configure($list_display, array(), array('id', 'status', 'due_dtime', 'modif_dtime'));
$pag->items_per_page = 10;
$pag->no_results_text = __('No issues were found.');
$pag->setFromRequest($request);
@ -776,6 +823,59 @@ class IDF_Views_Issue
'page_title' => $title,
'open' => $open,
'closed' => $closed,
'overdue' => $overdue,
'issues' => $pag,
'cloud' => 'closed_issues',
),
$request);
}
/**
* View list of issues for a given project with a given status.
*/
public $listOverdue_precond = array('IDF_Precondition::accessIssues');
public function listOverdue($request, $match)
{
$prj = $request->project;
$status = __('Overdue');
$title = sprintf(__('%s %s Issues'), (string) $prj, (string) $status);
// Get stats about the issues
$open = $prj->getIssueCountByStatus('open');
$closed = $prj->getIssueCountByStatus('closed');
$overdue = $prj->getIssueCountByDueDate();
// Paginator to paginate the issues
$pag = new Pluf_Paginator(new IDF_Issue());
$pag->class = 'recent-issues';
$pag->item_extra_props = array('project_m' => $prj,
'shortname' => $prj->shortname,
'current_user' => $request->user);
$pag->summary = __('This table shows the overdue issues.');
$otags = $prj->getTagIdsByStatus('open');
if (count($otags) == 0) $otags[] = 0;
$pag->forced_where = new Pluf_SQL('project=%s AND due_dtime < NOW() AND status IN ('.implode(', ', $otags).')', array($prj->id));
$pag->action = array('IDF_Views_Issue::listOverdue', array($prj->shortname, $status));
$pag->sort_order = array('due_dtime', 'DESC'); // will be reverted
$pag->sort_reverse_order = array('due_dtime');
$pag->sort_link_title = true;
$pag->extra_classes = array('a-c', '', 'a-c', '');
$list_display = array(
'id' => __('Id'),
array('summary', 'IDF_Views_Issue_SummaryAndLabels', __('Summary')),
array('status', 'IDF_Views_Issue_ShowStatus', __('Status')),
array('due_dtime', 'IDF_Views_Issue_DueDate', __('Due Date')),
array('modif_dtime', 'Pluf_Paginator_DateAgo', __('Last Updated')),
);
$pag->configure($list_display, array(), array('id', 'status', 'due_dtime', 'modif_dtime'));
$pag->items_per_page = 10;
$pag->no_results_text = __('No issues were found.');
$pag->setFromRequest($request);
return Pluf_Shortcuts_RenderToResponse('idf/issues/index.html',
array('project' => $prj,
'page_title' => $title,
'open' => $open,
'closed' => $closed,
'overdue' => $overdue,
'issues' => $pag,
'cloud' => 'closed_issues',
),
@ -791,12 +891,17 @@ class IDF_Views_Issue
$prj = $request->project;
$tag = Pluf_Shortcuts_GetObjectOr404('IDF_Tag', $match[2]);
$status = $match[3];
if ($tag->project != $prj->id or !in_array($status, array('open', 'closed'))) {
if ($tag->project != $prj->id or !in_array($status, array('open', 'closed', 'overdue'))) {
throw new Pluf_HTTP_Error404();
}
if ($status == 'open') {
$title = sprintf(__('%1$s Issues with Label %2$s'), (string) $prj,
(string) $tag);
} elseif ($status == 'overdue') {
$title = sprintf(__('%1$s Overdue Issues with Label %2$s'), (string) $prj,
(string) $tag);
$overdue_status = true;
$status = 'open';
} else {
$title = sprintf(__('%1$s Closed Issues with Label %2$s'),
(string) $prj, (string) $tag);
@ -804,6 +909,7 @@ class IDF_Views_Issue
// Get stats about the open/closed issues having this tag.
$open = $prj->getIssueCountByStatus('open', $tag);
$closed = $prj->getIssueCountByStatus('closed', $tag);
$overdue = $prj->getIssueCountByDueDate('overdue', $tag);
// Paginator to paginate the issues
$pag = new Pluf_Paginator(new IDF_Issue());
$pag->model_view = 'join_tags';
@ -815,6 +921,9 @@ class IDF_Views_Issue
$otags = $prj->getTagIdsByStatus($status);
if (count($otags) == 0) $otags[] = 0;
$pag->forced_where = new Pluf_SQL('project=%s AND idf_tag_id=%s AND status IN ('.implode(', ', $otags).')', array($prj->id, $tag->id));
if (isset($overdue_status)) {
$pag->forced_where->SAnd(new Pluf_SQL('due_dtime < NOW()'));
}
$pag->action = array('IDF_Views_Issue::listLabel', array($prj->shortname, $tag->id, $status));
$pag->sort_order = array('modif_dtime', 'ASC'); // will be reverted
$pag->sort_reverse_order = array('modif_dtime');
@ -824,9 +933,10 @@ class IDF_Views_Issue
'id' => __('Id'),
array('summary', 'IDF_Views_Issue_SummaryAndLabels', __('Summary')),
array('status', 'IDF_Views_Issue_ShowStatus', __('Status')),
array('due_dtime', 'IDF_Views_Issue_DueDate', __('Due Date')),
array('modif_dtime', 'Pluf_Paginator_DateAgo', __('Last Updated')),
);
$pag->configure($list_display, array(), array('id', 'status', 'modif_dtime'));
$pag->configure($list_display, array(), array('id', 'status', 'due_dtime', 'modif_dtime'));
$pag->items_per_page = 10;
$pag->no_results_text = __('No issues were found.');
$pag->setFromRequest($request);
@ -842,6 +952,7 @@ class IDF_Views_Issue
'open' => $open,
'label' => $tag,
'closed' => $closed,
'overdue' => $overdue,
'issues' => $pag,
),
$request);
@ -1002,6 +1113,28 @@ class IDF_Views_Issue
$auto['auto_relation_types'] = substr($auto['auto_relation_types'], 0, -2);
return $auto;
}
public static function getDateShortcuts()
{
return array(
'date_shortcuts' => array(
__('Soon') => array(
__('Today') => date('Y-m-d'),
__('Tomorrow') => date('Y-m-d', strtotime('tomorrow')),
__('2 Days') => date('Y-m-d', strtotime('+2 days')),
),
__('Midterm') => array(
__('Friday') => date('Y-m-d', strtotime('next friday')),
__('1 Week') => date('Y-m-d', strtotime('+1 week')),
__('A Fortnight') => date('Y-m-d', strtotime('+2 week')),
),
__('Longterm') => array(
__('End of the Month') => date('Y-m-d', strtotime('last day of this month')),
__('1 Month') => date('Y-m-d', strtotime('+1 month')),
),
),
);
}
}
/**
@ -1015,6 +1148,16 @@ function IDF_Views_Issue_SummaryAndLabelsUnknownProject($field, $issue, $extra='
return IDF_Views_Issue_SummaryAndLabels ($field, $issue, $extra);
}
/**
* Get the date value for the Due Date table column
*/
function IDF_Views_Issue_DueDate($field, $issue, $extra='')
{
if($issue->$field) {
return Pluf_Template_dateFormat($issue->$field);
}
}
/**
* Display the summary of an issue, then on a new line, display the
* list of labels with a link to a view "by label only".
@ -1037,8 +1180,12 @@ function IDF_Views_Issue_SummaryAndLabels($field, $issue, $extra='')
$s = '<img style="vertical-align: text-bottom;" src="'.Pluf_Template_Tag_MediaUrl::url('/idf/img/star.png').'" alt="'.__('On your watch list.').'" /> ';
}
$out = '';
if ('' != $issue->due_dtime and (time() >= strtotime($issue->due_dtime)) and
in_array($issue->status, $issue->get_project()->getTagIdsByStatus('open'))) {
$out = ' <span class="overdue">' . __('overdue') . '</span>';
}
if (count($tags)) {
$out = '<br /><span class="note">'.implode(', ', $tags).'</span>';
$out .= '<br /><span class="note">'.implode(', ', $tags).'</span>';
}
return $s.sprintf('<a href="%s">%s</a>', $edit, Pluf_esc($issue->summary)).$out;
}

View File

@ -506,7 +506,7 @@ $cfg['idf_strong_key_check'] = false;
# submitted as value of the HTTP header 'Post-Commit-Hook-Hmac' during
# such a request. Since newer versions of Indefero use the same authentication
# mechanism (based on the same secret key) for other web hooks of the same
# project as well, the name of this HTTP header was no longer appropriate
# project as well, the name of this HTTP header was no longer appropriate
# and as such changed to simply 'Web-Hook-Hmac'.
#
# Setting the following configuration option to 'compat' now restores the
@ -533,7 +533,7 @@ $cfg['activity_section_weights'] = array(
'wiki' => 2,
'downloads' => 1,
'review' => 1,
);
);
# Here you can define the timespan in days how long the activity calculation
# process should look into the history to get meaningful activity values for
@ -544,5 +544,4 @@ $cfg['activity_section_weights'] = array(
# high enough to show a proper activity index for those projects as well.
$cfg['activity_lookback'] = 7;
return $cfg;
return $cfg;

View File

@ -163,6 +163,11 @@ $ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/status/(\w+)/$#',
'model' => 'IDF_Views_Issue',
'method' => 'listStatus');
$ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/due/overdue/$#',
'base' => $base,
'model' => 'IDF_Views_Issue',
'method' => 'listOverdue');
$ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/label/(\d+)/(\w+)/$#',
'base' => $base,
'model' => 'IDF_Views_Issue',

View File

@ -25,6 +25,7 @@
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" type="text/css" href="{media '/idf/css/yui.css'}" />
<link rel="stylesheet" type="text/css" href="{media '/idf/css/style.css'}" />
<link rel="stylesheet" type="text/css" href="{media '/idf/css/jquery-ui-1.8.18.custom.css'}" />
<link rel="icon" type="image/png" href="{media '/idf/img/favicon.png'}" />
<!--[if lt IE 7]>
<link rel="stylesheet" type="text/css" href="{media '/idf/css/ie6.css'}" />
@ -32,6 +33,7 @@
{block extraheader}{/block}
<title>{block pagetitle}{$page_title|strip_tags}{/block}{if $project} - {$project.shortdesc}{/if}</title>
<script type="text/javascript" src="{media '/idf/js/jquery-1.7.2.min.js'}"></script>
<script type="text/javascript" src="{media '/idf/js/jquery-ui-1.8.18.custom.min.js'}"></script>
{appversion}
</head>
<body>

View File

@ -25,6 +25,7 @@
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" type="text/css" href="{media '/idf/css/yui.css'}" />
<link rel="stylesheet" type="text/css" href="{media '/idf/css/style.css'}" />
<link rel="stylesheet" type="text/css" href="{media '/idf/css/jquery-ui-1.8.18.custom.css'}" />
<link rel="icon" type="image/png" href="{media '/idf/img/favicon.png'}" />
<!--[if lt IE 7]>
<link rel="stylesheet" type="text/css" href="{media '/idf/css/ie6.css'}" />
@ -32,6 +33,7 @@
{block extraheader}{/block}
<title>{block pagetitle}{$page_title|strip_tags}{/block}</title>
<script type="text/javascript" src="{media '/idf/js/jquery-1.7.2.min.js'}"></script>
<script type="text/javascript" src="{media '/idf/js/jquery-ui-1.8.18.custom.min.js'}"></script>
{appversion}
</head>
<body>

View File

@ -25,6 +25,7 @@
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" type="text/css" href="{media '/idf/css/yui.css'}" />
<link rel="stylesheet" type="text/css" href="{media '/idf/css/style.css'}" />
<link rel="stylesheet" type="text/css" href="{media '/idf/css/jquery-ui-1.8.18.custom.css'}" />
<link rel="icon" type="image/png" href="{media '/idf/img/favicon.png'}" />
<!--[if lt IE 7]>
<link rel="stylesheet" type="text/css" href="{media '/idf/css/ie6.css'}" />
@ -32,6 +33,7 @@
{block extraheader}{/block}
<title>{block pagetitle}{$page_title|strip_tags}{/block}{if $project} - {$project.shortdesc}{/if}</title>
<script type="text/javascript" src="{media '/idf/js/jquery-1.7.2.min.js'}"></script>
<script type="text/javascript" src="{media '/idf/js/jquery-ui-1.8.18.custom.min.js'}"></script>
{appversion}
</head>
<body>

View File

@ -10,8 +10,10 @@
{block context}
{aurl 'open_url', 'IDF_Views_Issue::listLabel', array($project.shortname, $label.id, 'open')}
{aurl 'closed_url', 'IDF_Views_Issue::listLabel', array($project.shortname, $label.id, 'closed')}
{aurl 'overdue_url', 'IDF_Views_Issue::listLabel', array($project.shortname, $label.id, 'overdue')}
{blocktrans}<p><strong>Open issues:</strong> <a href="{$open_url}">{$open}</a></p>
<p><strong>Closed issues:</strong> <a href="{$closed_url}">{$closed}</a></p>
<p><span>Overdue:</span> <a href="{$overdue_url}">{$overdue}</a></p>
{/blocktrans}
<p><strong>{trans 'Label:'}</strong>
{aurl 'url', 'IDF_Views_Issue::listLabel', array($project.shortname, $label.id, 'open')}

View File

@ -63,6 +63,24 @@
</td>
</tr>
<tr>
<th>{$form.f.due_dtime.labelTag}:</th>
<td>{if $form.f.due_dtime.errors}{$form.f.due_dtime.fieldErrors}{/if}
{$form.f.due_dtime|unsafe}
<div id="due_dtime_wrapper">
<a href="#" id="due_dtime_shortcut_link">Date shortcuts&hellip;</a>
{if $date_shortcuts}
<dl id="due_dtime_more_shortcuts" style="display: none">
{foreach $date_shortcuts as $time_span => $shortcuts}
<dt>{$time_span}</dt>
{foreach $shortcuts as $title => $date}
<dd><a href="javascript:void(0);" rel="{$date}" class="due_dtime_shortcut">{$title}</a></dd>
{/foreach}
{/foreach}
</dl>
{/if}
</div>
</td>
<tr>
<th>{$form.f.relation_type0.labelTag}:</th>
<td>
{if $form.f.relation_type0.errors}{$form.f.relation_type0.fieldErrors}{/if}
@ -108,7 +126,21 @@
<script type="text/javascript">
document.getElementById('id_summary').focus();{literal}
$(document).ready(function(){
$("#id_due_dtime").datepicker({
changeYear: true,
changeMonth: true,
yearRange: '-0:+5',
constrainInput: false,
dateFormat: 'yy-mm-dd'
});
$('#due_dtime_wrapper').mouseover(function(){
$('#due_dtime_more_shortcuts').show();
}).mouseout(function(){
$('#due_dtime_more_shortcuts').hide();
});
$(".due_dtime_shortcut").click(function(){
$('#id_due_dtime').val($(this).attr('rel'));
});
// Hide the upload forms, we insert before the first attach file
// row an "Attach File" little link.
// We hide all the rows.

View File

@ -14,7 +14,7 @@
</ul>{/if}
{if $c.changes}
{foreach $c.changes as $w => $v}
<strong>{if $w == 'su'}{trans 'Summary:'}{/if}{if $w == 'st'}{trans 'Status:'}{/if}{if $w == 'ow'}{trans 'Owner:'}{/if}{if $w == 'lb'}{trans 'Labels:'}{/if}{if $w == 'rel'}{trans 'Relations:'}{/if}</strong>
<strong>{if $w == 'su'}{trans 'Summary:'}{/if}{if $w == 'st'}{trans 'Status:'}{/if}{if $w == 'ow'}{trans 'Owner:'}{/if}{if $w == 'lb'}{trans 'Labels:'}{/if}{if $w == 'rel'}{trans 'Relations:'}{/if}{if $w == 'du'}{trans 'Due date:'}{/if}</strong>
{if $w == 'lb' or $w == 'rel'}
{foreach $v as $t => $ls}
{foreach $ls as $l}

View File

@ -7,6 +7,8 @@
{block context}
{aurl 'open_url', 'IDF_Views_Issue::forgeWatchList', array('open')}
{aurl 'closed_url', 'IDF_Views_Issue::forgeWatchList', array('closed')}
{aurl 'overdue_url', 'IDF_Views_Issue::forgeWatchList', array('overdue')}
{blocktrans}<p><strong>Open issues:</strong> <a href="{$open_url}">{$open}</a></p>
<p><strong>Closed issues:</strong> <a href="{$closed_url}">{$closed}</a></p>{/blocktrans}
{/block}
<p><strong>Closed issues:</strong> <a href="{$closed_url}">{$closed}</a></p>
<p><span>Overdue:</span> <a href="{$overdue_url}">{$overdue}</a></p>{/blocktrans}
{/block}

View File

@ -10,8 +10,10 @@
{block context}
{aurl 'open_url', 'IDF_Views_Issue::index', array($project.shortname)}
{aurl 'closed_url', 'IDF_Views_Issue::listStatus', array($project.shortname, 'closed')}
{aurl 'overdue_url', 'IDF_Views_Issue::listOverdue', array($project.shortname, 'Overdue', 'overdue')}
{blocktrans}<p><strong>Open issues:</strong> <a href="{$open_url}">{$open}</a></p>
<p><strong>Closed issues:</strong> <a href="{$closed_url}">{$closed}</a></p>{/blocktrans}
<p><strong>Closed issues:</strong> <a href="{$closed_url}">{$closed}</a></p>
<p><span>Overdue:</span> <a href="{$overdue_url}">{$overdue}</a></p>{/blocktrans}
{assign $cloud_url = 'IDF_Views_Issue::listLabel'}
{include 'idf/tags-cloud.html'}
{/block}

View File

@ -6,6 +6,7 @@
{trans 'Project:'} {$project.name|safe}
{trans 'Status:'} {$issue.get_status.name|safe}
{trans 'Reported by:'} {$issue.get_submitter|safe}
{if $issue.due_dtime}{trans 'Due date:'} {$issue.due_dtime|date|safe}{/if}
{assign $tags = $issue.get_tags_list()}{if $tags.count()}{trans 'Labels:'}
{foreach $tags as $tag} {$tag.class|safe}:{$tag.name|safe}
{/foreach}{/if}

View File

@ -6,6 +6,7 @@
{trans 'Project:'} {$project.name|safe}
{trans 'Status:'} {$issue.get_status.name}
{trans 'Reported by:'} {$issue.get_submitter|safe}
{if $issue.due_dtime}{trans 'Due date:'} {$issue.due_dtime|date|safe}{/if}
{trans 'URL:'} {$url_base}{url 'IDF_Views_Issue::view', array($project.shortname, $issue.id)}
{assign $tags = $issue.get_tags_list()}{if $tags.count()}{trans 'Labels:'}
{foreach $tags as $tag} {$tag.class|safe}:{$tag.name|safe}
@ -16,7 +17,7 @@
{if strlen($c.content) > 0}{$c.content|safe}{/if}{if $c.changedIssue()}
{foreach $c.changes as $w => $v}
{if $w == 'su'}{trans 'Summary:'}{/if}{if $w == 'st'}{trans 'Status:'}{/if}{if $w == 'ow'}{trans 'Owner:'}{/if}{if $w == 'lb'}{trans 'Labels:'}{/if}{if $w == 'rel'}{trans 'Relations:'}{/if} {if $w == 'lb' or $w == 'rel'}{foreach $v as $t => $ls}{foreach $ls as $l}{if $t == 'rem'}-{/if}{$l} {/foreach}{/foreach}{else}{$v}{/if}{/foreach}{/if}{assign $attachments = $c.get_attachment_list()}{if $attachments.count() > 0}
{if $w == 'su'}{trans 'Summary:'}{/if}{if $w == 'st'}{trans 'Status:'}{/if}{if $w == 'ow'}{trans 'Owner:'}{/if}{if $w == 'du'}{trans 'Due date:'}{/if}{if $w == 'lb'}{trans 'Labels:'}{/if}{if $w == 'rel'}{trans 'Relations:'}{/if} {if $w == 'lb' or $w == 'rel'}{foreach $v as $t => $ls}{foreach $ls as $l}{if $t == 'rem'}-{/if}{$l} {/foreach}{/foreach}{else}{$v}{/if}{/foreach}{/if}{assign $attachments = $c.get_attachment_list()}{if $attachments.count() > 0}
{trans 'Attachments:'}{foreach $attachments as $a}
- {$a.filename|safe} - {$a.filesize|ssize}

View File

@ -12,6 +12,8 @@
{block context}
{aurl 'open_url', 'IDF_Views_Issue::watchList', array($project.shortname, 'open')}
{aurl 'closed_url', 'IDF_Views_Issue::watchList', array($project.shortname, 'closed')}
{aurl 'overdue_url', 'IDF_Views_Issue::watchList', array($project.shortname, 'overdue')}
{blocktrans}<p><strong>Open issues:</strong> <a href="{$open_url}">{$open}</a></p>
<p><strong>Closed issues:</strong> <a href="{$closed_url}">{$closed}</a></p>{/blocktrans}
{/block}
<p><strong>Closed issues:</strong> <a href="{$closed_url}">{$closed}</a></p>
<p><span>Overdue:</span> <a href="{$overdue_url}">{$overdue}</a></p>{/blocktrans}
{/block}

View File

@ -10,13 +10,16 @@
{block context}
{aurl 'open_url', 'IDF_Views_Issue::searchStatus', array($project.shortname, 'open'), array('q' => $query)}
{aurl 'closed_url', 'IDF_Views_Issue::searchStatus', array($project.shortname, 'closed'), array('q' => $query)}
{aurl 'overdue_url', 'IDF_Views_Issue::searchStatus', array($project.shortname, 'overdue'), array('q' => $query)}
{if $tag != null}
{aurl 'open_url', 'IDF_Views_Issue::searchLabel', array($project.shortname, $tag.id, 'open'), array('q' => $query)}
{aurl 'closed_url', 'IDF_Views_Issue::searchLabel', array($project.shortname, $tag.id, 'closed'), array('q' => $query)}
{aurl 'overdue_url', 'IDF_Views_Issue::searchLabel', array($project.shortname, $tag.id, 'overdue'), array('q' => $query)}
{/if}
{blocktrans}
<p><strong>Found open issues:</strong> <a href="{$open_url}">{$open}</a></p>
<p><strong>Found closed issues:</strong> <a href="{$closed_url}">{$closed}</a></p>{/blocktrans}
<p><strong>Found closed issues:</strong> <a href="{$closed_url}">{$closed}</a></p>
<p>Found overdue issues: <a href="{$overdue_url}">{$overdue}</a></p>{/blocktrans}
{if $tag !== null}
{blocktrans}<p><strong>Label:</strong>
<a href="{$open_url}" class="label"><strong>{$tag.class}:</strong>{$tag.name}</a></p>{/blocktrans}

View File

@ -103,6 +103,34 @@
</table>
</div>
{/if}
{if $duedateStatistics}
<div>
<h2>{blocktrans}Unresolved: By Due Date{/blocktrans}</h2>
<table class='issue-summary'>
<tbody>
<tr>
<td class="name">
{aurl 'url', 'IDF_Views_Issue::listOverdue', array($project.shortname, 'overdue', 'due')}
<a href="{$url}">{blocktrans}Overdue{/blocktrans}</a>
</td>
<td class="count">{$duedateStatistics[0]}</td>
<td class="graph">
<table class='graph'>
<tbody><tr>
<td style="width:{$duedateStatistics[1] * 0.8 + 1}%" class="graph-color" valign="center">
<div class="colour-bar"></div>
</td>
<td class="graph-percent">{$duedateStatistics[1]}%</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</div>
{/if}
</div>
{/if}
{/block}

View File

@ -40,7 +40,7 @@
{if $i> 0 and $c.changedIssue()}
<div class="issue-changes">
{foreach $c.changes as $w => $v}
<strong>{if $w == 'su'}{trans 'Summary:'}{/if}{if $w == 'st'}{trans 'Status:'}{/if}{if $w == 'ow'}{trans 'Owner:'}{/if}{if $w == 'lb'}{trans 'Labels:'}{/if}{if $w == 'rel'}{trans 'Relations:'}{/if}</strong>
<strong>{if $w == 'su'}{trans 'Summary:'}{/if}{if $w == 'st'}{trans 'Status:'}{/if}{if $w == 'ow'}{trans 'Owner:'}{/if}{if $w == 'du'}{trans 'Due date:'}{/if}{if $w == 'lb'}{trans 'Labels:'}{/if}{if $w == 'rel'}{trans 'Relations:'}{/if}</strong>
{if $w == 'lb' or $w == 'rel'}
{foreach $v as $t => $ls}
{foreach $ls as $l}
@ -128,6 +128,24 @@
{$form.f.owner|unsafe}
</td>
</tr>
<th>{$form.f.due_dtime.labelTag}:</th>
<td>{if $form.f.due_dtime.errors}{$form.f.due_dtime.fieldErrors}{/if}
{$form.f.due_dtime|unsafe}
<div id="due_dtime_wrapper">
<a href="#" id="due_dtime_shortcut_link">Date shortcuts&hellip;</a>
{if $date_shortcuts}
<dl id="due_dtime_more_shortcuts" style="display: none">
{foreach $date_shortcuts as $time_span => $shortcuts}
<dt>{$time_span}</dt>
{foreach $shortcuts as $title => $date}
<dd><a href="javascript:void(0);" rel="{$date}" class="due_dtime_shortcut">{$title}</a></dd>
{/foreach}
{/foreach}
</dl>
{/if}
</div>
</td>
<tr>
<tr>
<th>{$form.f.relation_type0.labelTag}:</th>
<td>
@ -180,6 +198,9 @@
<strong>{trans 'Owner:'}</strong> {showuser $issue.get_owner(), $request}
</p>{/if}
{if $interested > 0}<p><strong>{trans 'Followed by:'}</strong> {blocktrans $interested}{$interested} person{plural}{$interested} persons{/blocktrans}</p>{/if}
{if $issue.due_dtime}
<p><strong>{trans 'Due Date:'}</strong> {$issue.due_dtime|date}</p>
{/if}
{assign $tags = $issue.get_tags_list()}{if $tags.count()}
<p>
<strong>{trans 'Labels:'}</strong><br />
@ -209,7 +230,21 @@
<script type="text/javascript">
{literal}
$(document).ready(function(){
$("#id_due_dtime").datepicker({
changeYear: true,
changeMonth: true,
yearRange: '-0:+5',
constrainInput: false,
dateFormat: 'yy-mm-dd'
});
$('#due_dtime_wrapper').mouseover(function(){
$('#due_dtime_more_shortcuts').show();
}).mouseout(function(){
$('#due_dtime_more_shortcuts').hide();
});
$(".due_dtime_shortcut").click(function(){
$('#id_due_dtime').val($(this).attr('rel'));
});
// Hide the upload forms, we insert before the first attach file
// row an "Attach File" little link.
// We hide all the rows.

View File

@ -0,0 +1,354 @@
/*
* jQuery UI CSS Framework 1.8.18
*
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/UI/Theming/API
*/
/* Layout helpers
----------------------------------*/
.ui-helper-hidden { display: none; }
.ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); }
.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }
.ui-helper-clearfix:before, .ui-helper-clearfix:after { content: ""; display: table; }
.ui-helper-clearfix:after { clear: both; }
.ui-helper-clearfix { zoom: 1; }
.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }
/* Interaction Cues
----------------------------------*/
.ui-state-disabled { cursor: default !important; }
/* Icons
----------------------------------*/
/* states and images */
.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }
/* Misc visuals
----------------------------------*/
/* Overlays */
.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
/*
* jQuery UI CSS Framework 1.8.18
*
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/UI/Theming/API
*
* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana,Arial,sans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=cccccc&bgTextureHeader=03_highlight_soft.png&bgImgOpacityHeader=75&borderColorHeader=aaaaaa&fcHeader=222222&iconColorHeader=222222&bgColorContent=ffffff&bgTextureContent=01_flat.png&bgImgOpacityContent=75&borderColorContent=aaaaaa&fcContent=222222&iconColorContent=222222&bgColorDefault=e6e6e6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=75&borderColorDefault=d3d3d3&fcDefault=555555&iconColorDefault=888888&bgColorHover=dadada&bgTextureHover=02_glass.png&bgImgOpacityHover=75&borderColorHover=999999&fcHover=212121&iconColorHover=454545&bgColorActive=ffffff&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=aaaaaa&fcActive=212121&iconColorActive=454545&bgColorHighlight=fbf9ee&bgTextureHighlight=02_glass.png&bgImgOpacityHighlight=55&borderColorHighlight=fcefa1&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=02_glass.png&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=01_flat.png&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=01_flat.png&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px
*/
/* Component containers
----------------------------------*/
.ui-widget { font-family: Verdana,Arial,sans-serif; font-size: 1.1em; }
.ui-widget .ui-widget { font-size: 1em; }
.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Verdana,Arial,sans-serif; font-size: 1em; }
.ui-widget-content { border: 1px solid #aaaaaa; background: #ffffff url(/media/idf/img/jquery-ui/ui-bg_flat_75_ffffff_40x100.png) 50% 50% repeat-x; color: #222222; }
.ui-widget-content a { color: #222222; }
.ui-widget-header { border: 1px solid #aaaaaa; background: #cccccc url(/media/idf/img/jquery-ui/ui-bg_highlight-soft_75_cccccc_1x100.png) 50% 50% repeat-x; color: #222222; font-weight: bold; }
.ui-widget-header a { color: #222222; }
/* Interaction states
----------------------------------*/
.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #d3d3d3; background: #e6e6e6 url(/media/idf/img/jquery-ui/ui-bg_glass_75_e6e6e6_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #555555; }
.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #555555; text-decoration: none; }
.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #999999; background: #dadada url(/media/idf/img/jquery-ui/ui-bg_glass_75_dadada_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; }
.ui-state-hover a, .ui-state-hover a:hover { color: #212121; text-decoration: none; }
.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #aaaaaa; background: #ffffff url(/media/idf/img/jquery-ui/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; }
.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #212121; text-decoration: none; }
.ui-widget :active { outline: none; }
/* Interaction Cues
----------------------------------*/
.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fcefa1; background: #fbf9ee url(/media/idf/img/jquery-ui/ui-bg_glass_55_fbf9ee_1x400.png) 50% 50% repeat-x; color: #363636; }
.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; }
.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #fef1ec url(/media/idf/img/jquery-ui/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x; color: #cd0a0a; }
.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #cd0a0a; }
.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #cd0a0a; }
.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; }
.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; }
.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }
/* Icons
----------------------------------*/
/* states and images */
.ui-icon { width: 16px; height: 16px; background-image: url(/media/idf/img/jquery-ui/ui-icons_222222_256x240.png); }
.ui-widget-content .ui-icon {background-image: url(/media/idf/img/jquery-ui/ui-icons_222222_256x240.png); }
.ui-widget-header .ui-icon {background-image: url(/media/idf/img/jquery-ui/ui-icons_222222_256x240.png); }
.ui-state-default .ui-icon { background-image: url(/media/idf/img/jquery-ui/ui-icons_888888_256x240.png); }
.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(/media/idf/img/jquery-ui/ui-icons_454545_256x240.png); }
.ui-state-active .ui-icon {background-image: url(/media/idf/img/jquery-ui/ui-icons_454545_256x240.png); }
.ui-state-highlight .ui-icon {background-image: url(/media/idf/img/jquery-ui/ui-icons_2e83ff_256x240.png); }
.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(/media/idf/img/jquery-ui/ui-icons_cd0a0a_256x240.png); }
/* positioning */
.ui-icon-carat-1-n { background-position: 0 0; }
.ui-icon-carat-1-ne { background-position: -16px 0; }
.ui-icon-carat-1-e { background-position: -32px 0; }
.ui-icon-carat-1-se { background-position: -48px 0; }
.ui-icon-carat-1-s { background-position: -64px 0; }
.ui-icon-carat-1-sw { background-position: -80px 0; }
.ui-icon-carat-1-w { background-position: -96px 0; }
.ui-icon-carat-1-nw { background-position: -112px 0; }
.ui-icon-carat-2-n-s { background-position: -128px 0; }
.ui-icon-carat-2-e-w { background-position: -144px 0; }
.ui-icon-triangle-1-n { background-position: 0 -16px; }
.ui-icon-triangle-1-ne { background-position: -16px -16px; }
.ui-icon-triangle-1-e { background-position: -32px -16px; }
.ui-icon-triangle-1-se { background-position: -48px -16px; }
.ui-icon-triangle-1-s { background-position: -64px -16px; }
.ui-icon-triangle-1-sw { background-position: -80px -16px; }
.ui-icon-triangle-1-w { background-position: -96px -16px; }
.ui-icon-triangle-1-nw { background-position: -112px -16px; }
.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
.ui-icon-arrow-1-n { background-position: 0 -32px; }
.ui-icon-arrow-1-ne { background-position: -16px -32px; }
.ui-icon-arrow-1-e { background-position: -32px -32px; }
.ui-icon-arrow-1-se { background-position: -48px -32px; }
.ui-icon-arrow-1-s { background-position: -64px -32px; }
.ui-icon-arrow-1-sw { background-position: -80px -32px; }
.ui-icon-arrow-1-w { background-position: -96px -32px; }
.ui-icon-arrow-1-nw { background-position: -112px -32px; }
.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
.ui-icon-arrow-4 { background-position: 0 -80px; }
.ui-icon-arrow-4-diag { background-position: -16px -80px; }
.ui-icon-extlink { background-position: -32px -80px; }
.ui-icon-newwin { background-position: -48px -80px; }
.ui-icon-refresh { background-position: -64px -80px; }
.ui-icon-shuffle { background-position: -80px -80px; }
.ui-icon-transfer-e-w { background-position: -96px -80px; }
.ui-icon-transferthick-e-w { background-position: -112px -80px; }
.ui-icon-folder-collapsed { background-position: 0 -96px; }
.ui-icon-folder-open { background-position: -16px -96px; }
.ui-icon-document { background-position: -32px -96px; }
.ui-icon-document-b { background-position: -48px -96px; }
.ui-icon-note { background-position: -64px -96px; }
.ui-icon-mail-closed { background-position: -80px -96px; }
.ui-icon-mail-open { background-position: -96px -96px; }
.ui-icon-suitcase { background-position: -112px -96px; }
.ui-icon-comment { background-position: -128px -96px; }
.ui-icon-person { background-position: -144px -96px; }
.ui-icon-print { background-position: -160px -96px; }
.ui-icon-trash { background-position: -176px -96px; }
.ui-icon-locked { background-position: -192px -96px; }
.ui-icon-unlocked { background-position: -208px -96px; }
.ui-icon-bookmark { background-position: -224px -96px; }
.ui-icon-tag { background-position: -240px -96px; }
.ui-icon-home { background-position: 0 -112px; }
.ui-icon-flag { background-position: -16px -112px; }
.ui-icon-calendar { background-position: -32px -112px; }
.ui-icon-cart { background-position: -48px -112px; }
.ui-icon-pencil { background-position: -64px -112px; }
.ui-icon-clock { background-position: -80px -112px; }
.ui-icon-disk { background-position: -96px -112px; }
.ui-icon-calculator { background-position: -112px -112px; }
.ui-icon-zoomin { background-position: -128px -112px; }
.ui-icon-zoomout { background-position: -144px -112px; }
.ui-icon-search { background-position: -160px -112px; }
.ui-icon-wrench { background-position: -176px -112px; }
.ui-icon-gear { background-position: -192px -112px; }
.ui-icon-heart { background-position: -208px -112px; }
.ui-icon-star { background-position: -224px -112px; }
.ui-icon-link { background-position: -240px -112px; }
.ui-icon-cancel { background-position: 0 -128px; }
.ui-icon-plus { background-position: -16px -128px; }
.ui-icon-plusthick { background-position: -32px -128px; }
.ui-icon-minus { background-position: -48px -128px; }
.ui-icon-minusthick { background-position: -64px -128px; }
.ui-icon-close { background-position: -80px -128px; }
.ui-icon-closethick { background-position: -96px -128px; }
.ui-icon-key { background-position: -112px -128px; }
.ui-icon-lightbulb { background-position: -128px -128px; }
.ui-icon-scissors { background-position: -144px -128px; }
.ui-icon-clipboard { background-position: -160px -128px; }
.ui-icon-copy { background-position: -176px -128px; }
.ui-icon-contact { background-position: -192px -128px; }
.ui-icon-image { background-position: -208px -128px; }
.ui-icon-video { background-position: -224px -128px; }
.ui-icon-script { background-position: -240px -128px; }
.ui-icon-alert { background-position: 0 -144px; }
.ui-icon-info { background-position: -16px -144px; }
.ui-icon-notice { background-position: -32px -144px; }
.ui-icon-help { background-position: -48px -144px; }
.ui-icon-check { background-position: -64px -144px; }
.ui-icon-bullet { background-position: -80px -144px; }
.ui-icon-radio-off { background-position: -96px -144px; }
.ui-icon-radio-on { background-position: -112px -144px; }
.ui-icon-pin-w { background-position: -128px -144px; }
.ui-icon-pin-s { background-position: -144px -144px; }
.ui-icon-play { background-position: 0 -160px; }
.ui-icon-pause { background-position: -16px -160px; }
.ui-icon-seek-next { background-position: -32px -160px; }
.ui-icon-seek-prev { background-position: -48px -160px; }
.ui-icon-seek-end { background-position: -64px -160px; }
.ui-icon-seek-start { background-position: -80px -160px; }
/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
.ui-icon-seek-first { background-position: -80px -160px; }
.ui-icon-stop { background-position: -96px -160px; }
.ui-icon-eject { background-position: -112px -160px; }
.ui-icon-volume-off { background-position: -128px -160px; }
.ui-icon-volume-on { background-position: -144px -160px; }
.ui-icon-power { background-position: 0 -176px; }
.ui-icon-signal-diag { background-position: -16px -176px; }
.ui-icon-signal { background-position: -32px -176px; }
.ui-icon-battery-0 { background-position: -48px -176px; }
.ui-icon-battery-1 { background-position: -64px -176px; }
.ui-icon-battery-2 { background-position: -80px -176px; }
.ui-icon-battery-3 { background-position: -96px -176px; }
.ui-icon-circle-plus { background-position: 0 -192px; }
.ui-icon-circle-minus { background-position: -16px -192px; }
.ui-icon-circle-close { background-position: -32px -192px; }
.ui-icon-circle-triangle-e { background-position: -48px -192px; }
.ui-icon-circle-triangle-s { background-position: -64px -192px; }
.ui-icon-circle-triangle-w { background-position: -80px -192px; }
.ui-icon-circle-triangle-n { background-position: -96px -192px; }
.ui-icon-circle-arrow-e { background-position: -112px -192px; }
.ui-icon-circle-arrow-s { background-position: -128px -192px; }
.ui-icon-circle-arrow-w { background-position: -144px -192px; }
.ui-icon-circle-arrow-n { background-position: -160px -192px; }
.ui-icon-circle-zoomin { background-position: -176px -192px; }
.ui-icon-circle-zoomout { background-position: -192px -192px; }
.ui-icon-circle-check { background-position: -208px -192px; }
.ui-icon-circlesmall-plus { background-position: 0 -208px; }
.ui-icon-circlesmall-minus { background-position: -16px -208px; }
.ui-icon-circlesmall-close { background-position: -32px -208px; }
.ui-icon-squaresmall-plus { background-position: -48px -208px; }
.ui-icon-squaresmall-minus { background-position: -64px -208px; }
.ui-icon-squaresmall-close { background-position: -80px -208px; }
.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
/* Misc visuals
----------------------------------*/
/* Corner radius */
.ui-corner-all, .ui-corner-top, .ui-corner-left, .ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; -khtml-border-top-left-radius: 4px; border-top-left-radius: 4px; }
.ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; -khtml-border-top-right-radius: 4px; border-top-right-radius: 4px; }
.ui-corner-all, .ui-corner-bottom, .ui-corner-left, .ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; -khtml-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; }
.ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; -khtml-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; }
/* Overlays */
.ui-widget-overlay { background: #aaaaaa url(/media/idf/img/jquery-ui/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); }
.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(/media/idf/img/jquery-ui/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -khtml-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; }/*
* jQuery UI Datepicker 1.8.18
*
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/UI/Datepicker#theming
*/
.ui-datepicker { width: 17em; padding: .2em .2em 0; display: none; }
.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; }
.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; }
.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; }
.ui-datepicker .ui-datepicker-prev { left:2px; }
.ui-datepicker .ui-datepicker-next { right:2px; }
.ui-datepicker .ui-datepicker-prev-hover { left:1px; }
.ui-datepicker .ui-datepicker-next-hover { right:1px; }
.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; }
.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; }
.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; }
.ui-datepicker select.ui-datepicker-month-year {width: 100%;}
.ui-datepicker select.ui-datepicker-month,
.ui-datepicker select.ui-datepicker-year { width: 49%;}
.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; }
.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; }
.ui-datepicker td { border: 0; padding: 1px; }
.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; }
.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; }
.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; }
.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; }
/* with multiple calendars */
.ui-datepicker.ui-datepicker-multi { width:auto; }
.ui-datepicker-multi .ui-datepicker-group { float:left; }
.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; }
.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; }
.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; }
.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; }
.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; }
.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; }
.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; }
.ui-datepicker-row-break { clear:both; width:100%; font-size:0em; }
/* RTL support */
.ui-datepicker-rtl { direction: rtl; }
.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; }
.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; }
.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; }
.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; }
.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; }
.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; }
.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; }
.ui-datepicker-rtl .ui-datepicker-group { float:right; }
.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */
.ui-datepicker-cover {
display: none; /*sorry for IE5*/
display/**/: block; /*sorry for IE5*/
position: absolute; /*must have*/
z-index: -1; /*must have*/
filter: mask(); /*must have*/
top: -4px; /*must have*/
left: -4px; /*must have*/
width: 200px; /*must have*/
height: 200px; /*must have*/
}

View File

@ -184,6 +184,14 @@ table.recent-issues td {
vertical-align: top;
}
table.recent-issues td span.overdue {
font-weight: bold;
background-color: #c00;
color: #fff;
padding: 0 2px;
margin-left: 5px;
}
table.recent-issues tfoot th {
text-align: right;
}
@ -317,6 +325,72 @@ div.issue-submit-info h2 {
margin-top: 0;
}
#due_dtime_wrapper {
float: right;
width: 350px;
position: relative;
padding-left: 0 !important;
}
#due_dtime_shortcut_link {
text-decoration: none;
color: #000;
}
#due_dtime_wrapper > a {
padding-left: 5px;
padding-right: 5px;
margin-top: -3px;
padding-top: 3px;
}
#due_dtime_more_shortcuts {
display: none;
background: #A5E26A;
border-top: 0;
position: absolute;
margin: 1px 0 0;
z-index: 1000;
top: 1.1em;
-moz-border-radius: 0 0 3px 3px;
border-radius: 0 0 3px 3px;
-moz-box-shadow: 0 10px 20px #333;
-webkit-box-shadow: 0 10px 20px #333;
box-shadow: 0 10px 20px #333;
max-height: 400px;
min-width: 145px;
overflow-x: hidden;
overflow-y: auto;
padding: 0 5px 5px;
}
#due_dtime_more_shortcuts dt {
font-weight: bold;
margin-top: 2px;
}
#due_dtime_more_shortcuts dd {
margin-left: 6px;
}
#due_dtime_more_shortcuts a {
text-decoration: none;
padding: 0 2px;
}
#due_dtime_more_shortcuts a:hover {
background: #fff;
}
#due_dtime_wrapper:hover > a {
background: #A5E26A;
text-decoration: none;
}
#due_dtime_wrapper:hover a {
color: #2E3436;
}
span.label {
color: #204a87;
padding-left: 0.5em;
@ -610,7 +684,7 @@ span.ctrl-char {
cursor: default;
}
/* special formatting for the TAB character: make it wider, so it is rendered more properly */
/* special formatting for the TAB character: make it wider, so it is rendered more properly */
span.ctrl-char[title="0x09"] {
width: 24px;
}
@ -701,7 +775,7 @@ table.diff-linecounts.right-hidden tr > td + td {
table.diff-contents td {
line-height: 12px;
padding: 2px;
font-size: 90%;
font-size: 90%;
border: none;
white-space: pre;
}
@ -723,7 +797,7 @@ table.diff-contents td:hover > span.ctrl-char {
}
table.diff-contents td.added > span.ctrl-char {
background: #0A0;
background: #0A0;
}
table.diff-contents td.removed > span.ctrl-char {
@ -857,7 +931,7 @@ div.deprecated-page {
}
li.old-rev {
font-style: italic;
font-style: italic;
}
.delp {

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

File diff suppressed because one or more lines are too long