From 7fd401d0e0234982d89286315f29eaf61b8198af Mon Sep 17 00:00:00 2001 From: lkassianik <lyubakassianik@gmail.com> Date: Wed, 6 May 2015 18:41:48 -0700 Subject: [PATCH] First stab at Calendar day view sidebar Summary: Ref T4393, First stab at Calendar day view sidebar Test Plan: Open Calendar day view, sidebar should show today and the next 6 days, empty or not. Reviewers: epriestley, #blessed_reviewers, chad Reviewed By: epriestley, #blessed_reviewers Subscribers: Korvin, epriestley Maniphest Tasks: T4393 Differential Revision: https://secure.phabricator.com/D12742 --- resources/celerity/map.php | 4 +- .../PhabricatorCalendarEventSearchEngine.php | 4 +- src/infrastructure/time/PhabricatorTime.php | 11 ++ .../phui/calendar/PHUICalendarDayView.php | 148 +++++++++++++++++- .../css/phui/calendar/phui-calendar-day.css | 23 +++ 5 files changed, 183 insertions(+), 7 deletions(-) diff --git a/resources/celerity/map.php b/resources/celerity/map.php index 53b5069337..daa73b4445 100644 --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -119,7 +119,7 @@ return array( 'rsrc/css/layout/phabricator-hovercard-view.css' => '44394670', 'rsrc/css/layout/phabricator-side-menu-view.css' => 'c1db9e9c', 'rsrc/css/layout/phabricator-source-code-view.css' => '2ceee894', - 'rsrc/css/phui/calendar/phui-calendar-day.css' => '75b8cc4a', + 'rsrc/css/phui/calendar/phui-calendar-day.css' => 'c2eb34ce', 'rsrc/css/phui/calendar/phui-calendar-list.css' => 'c1d0ca59', 'rsrc/css/phui/calendar/phui-calendar-month.css' => 'a92e47d2', 'rsrc/css/phui/calendar/phui-calendar.css' => '8675968e', @@ -773,7 +773,7 @@ return array( 'phui-box-css' => '7b3a2eed', 'phui-button-css' => 'de610129', 'phui-calendar-css' => '8675968e', - 'phui-calendar-day-css' => '75b8cc4a', + 'phui-calendar-day-css' => 'c2eb34ce', 'phui-calendar-list-css' => 'c1d0ca59', 'phui-calendar-month-css' => 'a92e47d2', 'phui-crumbs-view-css' => '594d719e', diff --git a/src/applications/calendar/query/PhabricatorCalendarEventSearchEngine.php b/src/applications/calendar/query/PhabricatorCalendarEventSearchEngine.php index 3f14adbae8..5eada843d3 100644 --- a/src/applications/calendar/query/PhabricatorCalendarEventSearchEngine.php +++ b/src/applications/calendar/query/PhabricatorCalendarEventSearchEngine.php @@ -70,7 +70,7 @@ final class PhabricatorCalendarEventSearchEngine if ($saved->getParameter('display') == 'month') { $next->modify('+1 month'); } else if ($saved->getParameter('display') == 'day') { - $next->modify('+1 day'); + $next->modify('+6 day'); } $display_start = $start_day->format('U'); @@ -447,7 +447,7 @@ final class PhabricatorCalendarEventSearchEngine } else { $value = AphrontFormDateControlValue::newFromEpoch( $viewer, - PhabricatorTime::getNow()); + PhabricatorTime::getTodayMidnightDateTime($viewer)->format('U')); $value->setEnabled(false); } diff --git a/src/infrastructure/time/PhabricatorTime.php b/src/infrastructure/time/PhabricatorTime.php index d1eb281e1c..d2866d99c2 100644 --- a/src/infrastructure/time/PhabricatorTime.php +++ b/src/infrastructure/time/PhabricatorTime.php @@ -58,4 +58,15 @@ final class PhabricatorTime { return $timestamp; } + public static function getTodayMidnightDateTime($viewer) { + $timezone = new DateTimeZone($viewer->getTimezoneIdentifier()); + $today = new DateTime('@'.time()); + $today->setTimeZone($timezone); + $year = $today->format('Y'); + $month = $today->format('m'); + $day = $today->format('d'); + $today = new DateTime("{$year}-{$month}-{$day}", $timezone); + return $today; + } + } diff --git a/src/view/phui/calendar/PHUICalendarDayView.php b/src/view/phui/calendar/PHUICalendarDayView.php index 533fa0f446..ed17f88ab6 100644 --- a/src/view/phui/calendar/PHUICalendarDayView.php +++ b/src/view/phui/calendar/PHUICalendarDayView.php @@ -117,12 +117,155 @@ final class PHUICalendarDayView extends AphrontView { )); $header = $this->renderDayViewHeader(); + $sidebar = $this->renderSidebar(); - $day_box = (new PHUIObjectBoxView()) + $table_box = id(new PHUIObjectBoxView()) ->setHeader($header) ->appendChild($table); - return $day_box; + $column1 = phutil_tag( + 'div', + array( + 'class' => 'pm', + ), + $sidebar); + + $column2 = phutil_tag( + 'div', + array( + 'class' => 'pm', + ), + $table_box); + + $layout = id(new AphrontMultiColumnView()) + ->addColumn($column1, 'third') + ->addColumn($column2, 'thirds') + ->setFluidLayout(true) + ->setGutter(AphrontMultiColumnView::GUTTER_MEDIUM); + + $wrap = phutil_tag( + 'div', + array( + 'class' => 'ml', + ), + $layout); + + return phutil_tag( + 'div', + array(), + array( + $wrap, + )); + } + + private function renderSidebar() { + $this->events = msort($this->events, 'getEpochStart'); + $week_of_boxes = $this->getWeekOfBoxes(); + $filled_boxes = array(); + + foreach ($week_of_boxes as $box) { + $start = $box['start']; + $end = id(clone $start)->modify('+1 day'); + + $box = $box['box']; + $box_events = array(); + + foreach ($this->events as $event) { + if ($event->getEpochStart() >= $start->format('U') && + $event->getEpochStart() < $end->format('U')) { + $box_events[] = $event; + } + } + $filled_boxes[] = $this->renderSidebarBox($box_events, $box); + } + + return $filled_boxes; + } + + private function renderSidebarBox($events, $box) { + $user = $this->user; + $rows = array(); + + foreach ($events as $key => $event) { + $uri = $event->getURI(); + $name = $event->getName(); + $time = id(AphrontFormDateControlValue::newFromEpoch( + $user, + $event->getEpochStart())) + ->getValueTime(); + + $name = phutil_tag( + 'a', + array( + 'href' => $uri, + ), + $name); + + $name = phutil_tag( + 'td', + array( + 'class' => 'calendar-day-sidebar-column-name', + ), + $name); + + $time = phutil_tag( + 'td', + array( + 'class' => 'calendar-day-sidebar-column-time', + ), + $time); + + $rows[] = phutil_tag( + 'tr', + array( + 'class' => 'calendar-day-sidebar-row', + ), + array( + $name, + $time, + )); + } + + $table = phutil_tag( + 'table', + array( + 'class' => 'calendar-day-sidebar-today-table', + ), + $rows); + + $box->appendChild($table); + return $box; + } + + private function getWeekOfBoxes() { + $sidebar_day_boxes = array(); + + $display_start_day = $this->getDateTime(); + $display_end_day = id(clone $display_start_day)->modify('+6 day'); + + $box_start_time = clone $display_start_day; + + $today_time = PhabricatorTime::getTodayMidnightDateTime($this->user); + $tomorrow_time = clone $today_time; + $tomorrow_time->modify('+1 day'); + + while ($box_start_time <= $display_end_day) { + if ($box_start_time == $today_time) { + $title = pht('Today'); + } else if ($box_start_time == $tomorrow_time) { + $title = pht('Tomorrow'); + } else { + $title = $box_start_time->format('l'); + } + + $sidebar_day_boxes[] = array( + 'box' => id(new PHUIObjectBoxView())->setHeaderText($title), + 'start' => clone $box_start_time, + ); + + $box_start_time->modify('+1 day'); + } + return $sidebar_day_boxes; } private function renderDayViewHeader() { @@ -290,7 +433,6 @@ final class PHUICalendarDayView extends AphrontView { $events = msort($this->events, 'getEpochStart'); $clusters = array(); - foreach ($events as $event) { $destination_cluster_key = null; $event_start = $event->getEpochStart(); diff --git a/webroot/rsrc/css/phui/calendar/phui-calendar-day.css b/webroot/rsrc/css/phui/calendar/phui-calendar-day.css index bb07f8b8f8..6ac1c8436a 100644 --- a/webroot/rsrc/css/phui/calendar/phui-calendar-day.css +++ b/webroot/rsrc/css/phui/calendar/phui-calendar-day.css @@ -7,6 +7,29 @@ width: 100%; } +.calendar-day-sidebar-today-table { + width: 100%; + margin: 8px 0; +} + +.calendar-day-sidebar-column-name { + text-align: left; + color: {$bluetext}; + width: 60%; + padding: 4px 16px; +} + +.calendar-day-sidebar-column-name a { + color: {$bluetext}; +} + +.calendar-day-sidebar-column-time { + color: {$bluetext}; + text-align: right; + width: 40%; + padding: 4px 16px; +} + .phui-calendar-day-hour { width: 60px; color: {$lightgreytext};