1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-10 08:52:39 +01:00

Calendar day view should have forward/back controls to scroll through days

Summary: Ref T4393, Calendar day view should have forward/back controls to scroll through days

Test Plan: Open day view on first or last day of the month, scrolling backwards or forwards through days should correctly calculate the date of the next day and the previous day and correctly find events.

Reviewers: epriestley, #blessed_reviewers

Reviewed By: epriestley, #blessed_reviewers

Subscribers: Korvin, epriestley

Maniphest Tasks: T4393

Differential Revision: https://secure.phabricator.com/D12721
This commit is contained in:
lkassianik 2015-05-05 12:51:32 -07:00
parent 12dbb62d18
commit 14af40afa0
4 changed files with 170 additions and 40 deletions

View file

@ -42,7 +42,8 @@ final class PhabricatorCalendarApplication extends PhabricatorApplication {
return array( return array(
'/E(?P<id>[1-9]\d*)' => 'PhabricatorCalendarEventViewController', '/E(?P<id>[1-9]\d*)' => 'PhabricatorCalendarEventViewController',
'/calendar/' => array( '/calendar/' => array(
'(?:query/(?P<queryKey>[^/]+)/(?:(?P<year>\d+)/(?P<month>\d+)/)?)?' '(?:query/(?P<queryKey>[^/]+)/(?:(?P<year>\d+)/'.
'(?P<month>\d+)/)?(?:(?P<day>\d+)/)?)?'
=> 'PhabricatorCalendarEventListController', => 'PhabricatorCalendarEventListController',
'event/' => array( 'event/' => array(
'create/' 'create/'

View file

@ -10,10 +10,11 @@ final class PhabricatorCalendarEventListController
public function handleRequest(AphrontRequest $request) { public function handleRequest(AphrontRequest $request) {
$year = $request->getURIData('year'); $year = $request->getURIData('year');
$month = $request->getURIData('month'); $month = $request->getURIData('month');
$day = $request->getURIData('day');
$engine = new PhabricatorCalendarEventSearchEngine(); $engine = new PhabricatorCalendarEventSearchEngine();
if ($month && $year) { if ($month && $year) {
$engine->setCalendarYearAndMonth($year, $month); $engine->setCalendarYearAndMonthAndDay($year, $month, $day);
} }
$controller = id(new PhabricatorApplicationSearchController()) $controller = id(new PhabricatorApplicationSearchController())

View file

@ -57,7 +57,8 @@ final class PhabricatorCalendarEventSearchEngine
$max_range = $this->getDateTo($saved)->getEpoch(); $max_range = $this->getDateTo($saved)->getEpoch();
if ($saved->getParameter('display') == 'month') { if ($saved->getParameter('display') == 'month') {
list($start_month, $start_year) = $this->getDisplayMonthAndYear($saved); list($start_year, $start_month) =
$this->getDisplayYearAndMonthAndDay($saved);
$start_day = 1; $start_day = 1;
$end_year = ($start_month == 12) ? $start_year + 1 : $start_year; $end_year = ($start_month == 12) ? $start_year + 1 : $start_year;
@ -226,9 +227,10 @@ final class PhabricatorCalendarEventSearchEngine
return $names; return $names;
} }
public function setCalendarYearAndMonth($year, $month) { public function setCalendarYearAndMonthAndDay($year, $month, $day = null) {
$this->calendarYear = $year; $this->calendarYear = $year;
$this->calendarMonth = $month; $this->calendarMonth = $month;
$this->calendarDay = $day;
return $this; return $this;
} }
@ -309,7 +311,8 @@ final class PhabricatorCalendarEventSearchEngine
$viewer = $this->requireViewer(); $viewer = $this->requireViewer();
$now = time(); $now = time();
list($start_month, $start_year) = $this->getDisplayMonthAndYear($query); list($start_year, $start_month) =
$this->getDisplayYearAndMonthAndDay($query);
$now_year = phabricator_format_local_time($now, $viewer, 'Y'); $now_year = phabricator_format_local_time($now, $viewer, 'Y');
$now_month = phabricator_format_local_time($now, $viewer, 'm'); $now_month = phabricator_format_local_time($now, $viewer, 'm');
@ -373,12 +376,12 @@ final class PhabricatorCalendarEventSearchEngine
PhabricatorSavedQuery $query, PhabricatorSavedQuery $query,
array $handles) { array $handles) {
$viewer = $this->requireViewer(); $viewer = $this->requireViewer();
list($start_month, $start_year, $start_day) = list($start_year, $start_month, $start_day) =
$this->getDisplayMonthAndYearAndDay($query); $this->getDisplayYearAndMonthAndDay($query);
$day_view = new PHUICalendarDayView( $day_view = new PHUICalendarDayView(
$start_month,
$start_year, $start_year,
$start_month,
$start_day); $start_day);
$day_view->setUser($viewer); $day_view->setUser($viewer);
@ -395,39 +398,19 @@ final class PhabricatorCalendarEventSearchEngine
$day_view->addEvent($event); $day_view->addEvent($event);
} }
$day_view->setBrowseURI(
$this->getURI('query/'.$query->getQueryKey().'/'));
return $day_view; return $day_view;
} }
private function getDisplayMonthAndYear( private function getDisplayYearAndMonthAndDay(
PhabricatorSavedQuery $query) { PhabricatorSavedQuery $query) {
$viewer = $this->requireViewer(); $viewer = $this->requireViewer();
// get month/year from url
if ($this->calendarYear && $this->calendarMonth) { if ($this->calendarYear && $this->calendarMonth) {
$start_year = $this->calendarYear; $start_year = $this->calendarYear;
$start_month = $this->calendarMonth; $start_month = $this->calendarMonth;
} else { $start_day = $this->calendarDay ? $this->calendarDay : 1;
$epoch = $this->getDateFrom($query)->getEpoch();
if (!$epoch) {
$epoch = $this->getDateTo($query)->getEpoch();
if (!$epoch) {
$epoch = time();
}
}
$start_year = phabricator_format_local_time($epoch, $viewer, 'Y');
$start_month = phabricator_format_local_time($epoch, $viewer, 'm');
}
return array($start_month, $start_year);
}
private function getDisplayMonthAndYearAndDay(
PhabricatorSavedQuery $query) {
$viewer = $this->requireViewer();
if ($this->calendarYear && $this->calendarMonth && $this->calendarDay) {
$start_year = $this->calendarYear;
$start_month = $this->calendarMonth;
$start_day = $this->calendarDay;
} else { } else {
$epoch = $this->getDateFrom($query)->getEpoch(); $epoch = $this->getDateFrom($query)->getEpoch();
if (!$epoch) { if (!$epoch) {

View file

@ -5,6 +5,7 @@ final class PHUICalendarDayView extends AphrontView {
private $day; private $day;
private $month; private $month;
private $year; private $year;
private $browseURI;
private $events = array(); private $events = array();
public function addEvent(AphrontCalendarDayEventView $event) { public function addEvent(AphrontCalendarDayEventView $event) {
@ -12,6 +13,14 @@ final class PHUICalendarDayView extends AphrontView {
return $this; return $this;
} }
public function setBrowseURI($browse_uri) {
$this->browseURI = $browse_uri;
return $this;
}
private function getBrowseURI() {
return $this->browseURI;
}
public function __construct($year, $month, $day = null) { public function __construct($year, $month, $day = null) {
$this->day = $day; $this->day = $day;
$this->month = $month; $this->month = $month;
@ -21,11 +30,6 @@ final class PHUICalendarDayView extends AphrontView {
public function render() { public function render() {
require_celerity_resource('phui-calendar-day-css'); require_celerity_resource('phui-calendar-day-css');
$day_box = new PHUIObjectBoxView();
$day_of_week = $this->getDayOfWeek();
$header_text = $this->getDateTime()->format('F j, Y');
$header_text = $day_of_week.', '.$header_text;
$day_box->setHeaderText($header_text);
$hours = $this->getHoursOfDay(); $hours = $this->getHoursOfDay();
$hourly_events = array(); $hourly_events = array();
$rows = array(); $rows = array();
@ -112,9 +116,64 @@ final class PHUICalendarDayView extends AphrontView {
$rows, $rows,
)); ));
$day_box->appendChild($table); $header = $this->renderDayViewHeader();
return $day_box;
$day_box = (new PHUIObjectBoxView())
->setHeader($header)
->appendChild($table);
return $day_box;
}
private function renderDayViewHeader() {
$button_bar = null;
// check for a browseURI, which means we need "fancy" prev / next UI
$uri = $this->getBrowseURI();
if ($uri) {
list($prev_year, $prev_month, $prev_day) = $this->getPrevDay();
$prev_uri = $uri.$prev_year.'/'.$prev_month.'/'.$prev_day.'/';
list($next_year, $next_month, $next_day) = $this->getNextDay();
$next_uri = $uri.$next_year.'/'.$next_month.'/'.$next_day.'/';
$button_bar = new PHUIButtonBarView();
$left_icon = id(new PHUIIconView())
->setIconFont('fa-chevron-left bluegrey');
$left = id(new PHUIButtonView())
->setTag('a')
->setColor(PHUIButtonView::GREY)
->setHref($prev_uri)
->setTitle(pht('Previous Day'))
->setIcon($left_icon);
$right_icon = id(new PHUIIconView())
->setIconFont('fa-chevron-right bluegrey');
$right = id(new PHUIButtonView())
->setTag('a')
->setColor(PHUIButtonView::GREY)
->setHref($next_uri)
->setTitle(pht('Next Day'))
->setIcon($right_icon);
$button_bar->addButton($left);
$button_bar->addButton($right);
}
$day_of_week = $this->getDayOfWeek();
$header_text = $this->getDateTime()->format('F j, Y');
$header_text = $day_of_week.', '.$header_text;
$header = id(new PHUIHeaderView())
->setHeader($header_text);
if ($button_bar) {
$header->setButtonBar($button_bar);
}
return $header;
} }
private function updateEventsFromCluster($cluster, $hourly_events) { private function updateEventsFromCluster($cluster, $hourly_events) {
@ -194,6 +253,92 @@ final class PHUICalendarDayView extends AphrontView {
return $included_datetimes; return $included_datetimes;
} }
private function getNumberOfDaysInMonth($month, $year) {
$user = $this->user;
$timezone = new DateTimeZone($user->getTimezoneIdentifier());
list($next_year, $next_month) = $this->getNextYearAndMonth($month, $year);
$end_date = new DateTime("{$next_year}-{$next_month}-01", $timezone);
$end_epoch = $end_date->format('U');
$days = 0;
for ($day = 1; $day <= 31; $day++) {
$day_date = new DateTime("{$year}-{$month}-{$day}", $timezone);
$day_epoch = $day_date->format('U');
if ($day_epoch >= $end_epoch) {
break;
} else {
$days++;
}
}
return $days;
}
private function getPrevDay() {
$day = $this->day;
$month = $this->month;
$year = $this->year;
$prev_year = $year;
$prev_month = $month;
$prev_day = $day - 1;
if ($prev_day == 0) {
$prev_month--;
if ($prev_month == 0) {
$prev_year--;
$prev_month = 12;
}
$prev_day = $this->getNumberOfDaysInMonth($prev_month, $prev_year);
}
return array($prev_year, $prev_month, $prev_day);
}
private function getNextDay() {
$day = $this->day;
$month = $this->month;
$year = $this->year;
$next_year = $year;
$next_month = $month;
$next_day = $day + 1;
$days_in_month = $this->getNumberOfDaysInMonth($month, $year);
if ($next_day > $days_in_month) {
$next_day = 1;
$next_month++;
}
if ($next_month == 13) {
$next_year++;
$next_month = 1;
}
return array($next_year, $next_month, $next_day);
}
private function getNextYearAndMonth($month, $year) {
$next_year = $year;
$next_month = $month + 1;
if ($next_month == 13) {
$next_year = $year + 1;
$next_month = 1;
}
return array($next_year, $next_month);
}
private function getPrevYearAndMonth($month, $year) {
$prev_year = $year;
$prev_month = $month - 1;
if ($prev_month == 0) {
$prev_year = $year - 1;
$prev_month = 12;
}
return array($prev_year, $prev_month);
}
private function getDateTime() { private function getDateTime() {
$user = $this->user; $user = $this->user;