diff --git a/resources/celerity/map.php b/resources/celerity/map.php --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -8,7 +8,7 @@ return array( 'names' => array( 'core.pkg.css' => 'ed3d6355', - 'core.pkg.js' => '31eaf90a', + 'core.pkg.js' => '73942604', 'darkconsole.pkg.js' => 'e7393ebb', 'differential.pkg.css' => 'bb338e4b', 'differential.pkg.js' => '895b8d62', @@ -122,7 +122,7 @@ 'rsrc/css/layout/phabricator-source-code-view.css' => '2ceee894', 'rsrc/css/phui/calendar/phui-calendar-day.css' => '49037167', 'rsrc/css/phui/calendar/phui-calendar-list.css' => 'c1d0ca59', - 'rsrc/css/phui/calendar/phui-calendar-month.css' => 'a92e47d2', + 'rsrc/css/phui/calendar/phui-calendar-month.css' => '55953dd2', 'rsrc/css/phui/calendar/phui-calendar.css' => '8675968e', 'rsrc/css/phui/phui-action-header-view.css' => '89c497e7', 'rsrc/css/phui/phui-action-list.css' => '4f4d09f2', @@ -211,7 +211,7 @@ 'rsrc/externals/javelin/lib/Resource.js' => '44959b73', 'rsrc/externals/javelin/lib/Routable.js' => 'b3e7d692', 'rsrc/externals/javelin/lib/Router.js' => '29274e2b', - 'rsrc/externals/javelin/lib/Scrollbar.js' => '4f812f8a', + 'rsrc/externals/javelin/lib/Scrollbar.js' => '087e919c', 'rsrc/externals/javelin/lib/Sound.js' => '949c0fe5', 'rsrc/externals/javelin/lib/URI.js' => '6eff08aa', 'rsrc/externals/javelin/lib/Vector.js' => '2caa8fb8', @@ -681,7 +681,7 @@ 'javelin-resource' => '44959b73', 'javelin-routable' => 'b3e7d692', 'javelin-router' => '29274e2b', - 'javelin-scrollbar' => '4f812f8a', + 'javelin-scrollbar' => '087e919c', 'javelin-sound' => '949c0fe5', 'javelin-stratcom' => '6c53634d', 'javelin-tokenizer' => 'ab5f468d', @@ -779,7 +779,7 @@ 'phui-calendar-css' => '8675968e', 'phui-calendar-day-css' => '49037167', 'phui-calendar-list-css' => 'c1d0ca59', - 'phui-calendar-month-css' => 'a92e47d2', + 'phui-calendar-month-css' => '55953dd2', 'phui-crumbs-view-css' => '594d719e', 'phui-document-view-css' => '94d5dcd8', 'phui-feed-story-css' => 'c9f3a0b5', @@ -868,6 +868,12 @@ 'javelin-uri', 'phabricator-file-upload', ), + '087e919c' => array( + 'javelin-install', + 'javelin-dom', + 'javelin-stratcom', + 'javelin-vector', + ), '0a3f3021' => array( 'javelin-behavior', 'javelin-stratcom', @@ -1134,12 +1140,6 @@ 'javelin-stratcom', 'javelin-request', ), - '4f812f8a' => array( - 'javelin-install', - 'javelin-dom', - 'javelin-stratcom', - 'javelin-vector', - ), '4fdb476d' => array( 'javelin-behavior', 'javelin-stratcom', diff --git a/src/applications/calendar/query/PhabricatorCalendarEventSearchEngine.php b/src/applications/calendar/query/PhabricatorCalendarEventSearchEngine.php --- a/src/applications/calendar/query/PhabricatorCalendarEventSearchEngine.php +++ b/src/applications/calendar/query/PhabricatorCalendarEventSearchEngine.php @@ -57,8 +57,8 @@ $min_range = $this->getDateFrom($saved)->getEpoch(); $max_range = $this->getDateTo($saved)->getEpoch(); - if ($saved->getParameter('display') == 'month' || - $saved->getParameter('display') == 'day') { + if ($this->isMonthView($saved) || + $this->isDayQuery($saved)) { list($start_year, $start_month, $start_day) = $this->getDisplayYearAndMonthAndDay($saved); @@ -67,9 +67,9 @@ $timezone); $next = clone $start_day; - if ($saved->getParameter('display') == 'month') { + if ($this->isMonthView($saved)) { $next->modify('+1 month'); - } else if ($saved->getParameter('display') == 'day') { + } else if ($this->isDayQuery($saved)) { $next->modify('+6 day'); } @@ -269,9 +269,9 @@ PhabricatorSavedQuery $query, array $handles) { - if ($query->getParameter('display') == 'month') { + if ($this->isMonthView($query)) { return $this->buildCalendarView($events, $query, $handles); - } else if ($query->getParameter('display') == 'day') { + } else if ($this->isDayQuery($query)) { return $this->buildCalendarDayView($events, $query, $handles); } @@ -358,6 +358,7 @@ foreach ($statuses as $status) { $event = new AphrontCalendarEventView(); $event->setEpochRange($status->getDateFrom(), $status->getDateTo()); + $event->setIsAllDay($status->getIsAllDay()); $name_text = $handles[$status->getUserPHID()]->getName(); $status_text = $status->getName(); @@ -430,9 +431,14 @@ $epoch = time(); } } + if ($this->isMonthView($query)) { + $day = 1; + } else { + $day = phabricator_format_local_time($epoch, $viewer, 'd'); + } $start_year = phabricator_format_local_time($epoch, $viewer, 'Y'); $start_month = phabricator_format_local_time($epoch, $viewer, 'm'); - $start_day = phabricator_format_local_time($epoch, $viewer, 'd'); + $start_day = $day; } return array($start_year, $start_month, $start_day); } @@ -467,4 +473,23 @@ return $value; } + private function isMonthView(PhabricatorSavedQuery $query) { + if ($this->isDayQuery($query)) { + return false; + } + if ($query->getParameter('display') == 'month') { + return true; + } + } + + private function isDayQuery(PhabricatorSavedQuery $query) { + if ($query->getParameter('display') == 'day') { + return true; + } + if ($this->calendarDay) { + return true; + } + + return false; + } } diff --git a/src/view/phui/calendar/PHUICalendarDayView.php b/src/view/phui/calendar/PHUICalendarDayView.php --- a/src/view/phui/calendar/PHUICalendarDayView.php +++ b/src/view/phui/calendar/PHUICalendarDayView.php @@ -233,6 +233,7 @@ $this->rangeStart->getEpoch() > $day_end)) { $errors[] = pht('Day is out of query range'); } + return $errors; } private function renderSidebar() { diff --git a/src/view/phui/calendar/PHUICalendarListView.php b/src/view/phui/calendar/PHUICalendarListView.php --- a/src/view/phui/calendar/PHUICalendarListView.php +++ b/src/view/phui/calendar/PHUICalendarListView.php @@ -4,12 +4,21 @@ private $events = array(); private $blankState; + private $showMoreURI; public function addEvent(AphrontCalendarEventView $event) { $this->events[] = $event; return $this; } + public function setShowMoreURI($uri) { + $this->showMoreURI = $uri; + } + + public function getEventCount() { + return count($this->events); + } + public function showBlankState($state) { $this->blankState = $state; return $this; @@ -22,7 +31,7 @@ protected function getTagAttributes() { require_celerity_resource('phui-calendar-css'); require_celerity_resource('phui-calendar-list-css'); - return array('class' => 'phui-calendar-day-list'); + return array('class' => 'phui-calendar-event-list'); } protected function getTagContent() { @@ -30,27 +39,28 @@ return ''; } - $events = msort($this->events, 'getEpochStart'); - $singletons = array(); $allday = false; - foreach ($events as $event) { + foreach ($this->events as $event) { $color = $event->getColor(); + $start_epoch = $event->getEpochStart(); if ($event->getIsAllDay()) { $timelabel = pht('All Day'); + $dot = null; } else { $timelabel = phabricator_time( $event->getEpochStart(), $this->getUser()); + + $dot = phutil_tag( + 'span', + array( + 'class' => 'phui-calendar-list-dot', + ), + ''); } - $dot = phutil_tag( - 'span', - array( - 'class' => 'phui-calendar-list-dot', - ), - ''); $title = phutil_tag( 'span', array( @@ -64,10 +74,15 @@ ), $timelabel); + $class = 'phui-calendar-list-item phui-calendar-'.$color; + if ($event->getIsAllDay()) { + $class = $class.' all-day'; + } + $singletons[] = phutil_tag( 'li', array( - 'class' => 'phui-calendar-list-item phui-calendar-'.$color, + 'class' => $class, ), array( $dot, @@ -76,6 +91,23 @@ )); } + if (strlen($this->showMoreURI) > 0) { + $show_more_link = phutil_tag( + 'a', + array( + 'href' => $this->showMoreURI, + ), + pht('Show More')); + + $singletons[] = phutil_tag( + 'li', + array( + 'class' => $class, + ), + $show_more_link); + } + + if (empty($singletons)) { $singletons[] = phutil_tag( 'li', @@ -112,11 +144,13 @@ $description = pht('(%s)', $event->getName()); } + $class = 'phui-calendar-item-link'; + $anchor = javelin_tag( 'a', array( 'sigil' => 'has-tooltip', - 'class' => 'phui-calendar-item-link', + 'class' => $class, 'href' => '/E'.$event->getEventID(), 'meta' => array( 'tip' => $tip, diff --git a/src/view/phui/calendar/PHUICalendarMonthView.php b/src/view/phui/calendar/PHUICalendarMonthView.php --- a/src/view/phui/calendar/PHUICalendarMonthView.php +++ b/src/view/phui/calendar/PHUICalendarMonthView.php @@ -73,13 +73,12 @@ $markup = array(); - $empty_box = phutil_tag( - 'div', - array('class' => 'phui-calendar-day phui-calendar-empty'), - ''); - for ($ii = 0; $ii < $empty; $ii++) { - $markup[] = $empty_box; + $markup[] = array( + 'list' => null, + 'date' => null, + 'class' => 'phui-calendar-empty', + ); } $show_events = array(); @@ -88,7 +87,7 @@ $day_number = $day->format('j'); $holiday = idx($this->holidays, $day->format('Y-m-d')); - $class = 'phui-calendar-day'; + $class = 'phui-calendar-month-day'; $weekday = $day->format('w'); if ($day_number == $this->day) { @@ -102,8 +101,8 @@ $day->setTime(0, 0, 0); $epoch_start = $day->format('U'); - $day->modify('+1 day'); - $epoch_end = $day->format('U'); + + $epoch_end = id(clone $day)->modify('+1 day')->format('U'); if ($weekday == 0) { $show_events = array(); @@ -116,6 +115,7 @@ } $list_events = array(); + $all_day_events = array(); foreach ($events as $event) { if ($event->getEpochStart() >= $epoch_end) { // This list is sorted, so we can stop looking. @@ -123,57 +123,84 @@ } if ($event->getEpochStart() < $epoch_end && $event->getEpochEnd() > $epoch_start) { - $list_events[] = $event; + if ($event->getIsAllDay()) { + $all_day_events[] = $event; + } else { + $list_events[] = $event; + } } } $list = new PHUICalendarListView(); $list->setUser($this->user); - foreach ($list_events as $item) { + foreach ($all_day_events as $item) { $list->addEvent($item); } - - $holiday_markup = null; - if ($holiday) { - $name = $holiday->getName(); - $holiday_markup = phutil_tag( - 'div', - array( - 'class' => 'phui-calendar-holiday', - 'title' => $name, - ), - $name); + foreach ($list_events as $item) { + $list->addEvent($item); } - $markup[] = phutil_tag_div( - $class, - array( - phutil_tag_div('phui-calendar-date-number', $day_number), - $holiday_markup, - $list, - )); + $markup[] = array( + 'list' => $list, + 'date' => $day, + 'class' => $class, + ); } $table = array(); $rows = array_chunk($markup, 7); + foreach ($rows as $row) { $cells = array(); while (count($row) < 7) { - $row[] = $empty_box; + $row[] = array( + 'list' => null, + 'date' => null, + 'class' => 'phui-calendar-empty', + ); + } + foreach ($row as $cell) { + $cell_list = $cell['list']; + $class = $cell['class']; + $cells[] = phutil_tag( + 'td', + array( + 'class' => 'phui-calendar-month-event-list '.$class, + ), + $cell_list); } - $j = 0; + $table[] = phutil_tag('tr', array(), $cells); + + $cells = array(); foreach ($row as $cell) { - if ($j == 0) { - $cells[] = phutil_tag( - 'td', + $class = $cell['class']; + + if ($cell['date']) { + $cell_day = $cell['date']; + + $uri = $this->getBrowseURI(); + $date = $cell['date']; + $uri = $uri.$date->format('Y').'/'. + $date->format('m').'/'. + $date->format('d').'/'; + + $cell_day = phutil_tag( + 'a', array( - 'class' => 'phui-calendar-month-weekstart', + 'class' => 'phui-calendar-date-number', + 'href' => $uri, ), - $cell); + $cell_day->format('j')); } else { - $cells[] = phutil_tag('td', array(), $cell); + $cell_day = null; } - $j++; + + $cells[] = phutil_tag( + 'td', + array( + 'class' => 'phui-calendar-date-number-container '.$class, + ), + $cell_day); } $table[] = phutil_tag('tr', array(), $cells); } diff --git a/webroot/rsrc/css/phui/calendar/phui-calendar-month.css b/webroot/rsrc/css/phui/calendar/phui-calendar-month.css --- a/webroot/rsrc/css/phui/calendar/phui-calendar-month.css +++ b/webroot/rsrc/css/phui/calendar/phui-calendar-month.css @@ -17,13 +17,17 @@ } table.phui-calendar-view td { - border: 1px solid #dfdfdf; + border: solid #dfdfdf; + border-width: 1px 1px 0 1px; width: 14.2857%; /* This is one seventh, approximately. */ } -table.phui-calendar-view td div.phui-calendar-day { +table.phui-calendar-view tr td:first-child { + border-left-width: 0px; +} + +table.phui-calendar-view .phui-calendar-event-list { min-height: 125px; - position: relative; } .phui-calendar-holiday { @@ -37,20 +41,23 @@ border-left: none; } -.phui-calendar-date-number { - font-weight: normal; +table.phui-calendar-view a.phui-calendar-date-number { color: {$lightgreytext}; - padding: 4px; border-color: {$thinblueborder}; border-style: solid; - border-width: 0 0 1px 1px; - position: absolute; - background: #ffffff; - width: 16px; - height: 16px; + border-width: 1px 0 0 1px; + padding: 4px; + display: inline-block; + min-width: 16px; text-align: center; - top: 0; - right: 0; + background-color: #ffffff; +} + +table.phui-calendar-view td.phui-calendar-date-number-container { + font-weight: normal; + color: {$lightgreytext}; + border-width: 0 1px 0 1px; + text-align: right; } .phui-calendar-not-work-day { @@ -71,11 +78,30 @@ } .phui-calendar-view .phui-calendar-list { - padding: 8px; + padding: 1px; +} + +.phui-calendar-list-item.all-day span { + padding: 0; + margin: 0; +} + +.phui-calendar-view .phui-calendar-list li.phui-calendar-list-item.all-day { + margin: 0; + padding: 4px 8px; + background-color: {$lightpink}; +} + +li.phui-calendar-list-item.all-day:first-child { + margin-top: 0; +} + +.phui-calendar-view .phui-calendar-list li { + margin: 0 8px; } .phui-calendar-view .phui-calendar-list li:first-child { - margin-right: 16px; + margin-top: 8px; } .phui-calendar-view .phui-calendar-list-dot { @@ -95,6 +121,10 @@ word-break: break-word; } +li.phui-calendar-list-item.all-day .phui-calendar-list-title a{ + color: {$pink}; +} + .phui-calendar-view .phui-calendar-list-time { display: none; }