diff --git a/library/Notifications/Widget/Calendar/BaseGrid.php b/library/Notifications/Widget/Calendar/BaseGrid.php index d5dd7fb1a..732c38263 100644 --- a/library/Notifications/Widget/Calendar/BaseGrid.php +++ b/library/Notifications/Widget/Calendar/BaseGrid.php @@ -20,6 +20,7 @@ use ipl\Web\Url; use ipl\Web\Widget\Link; use SplObjectStorage; +use stdClass; use Traversable; abstract class BaseGrid extends BaseHtmlElement @@ -39,7 +40,8 @@ abstract class BaseGrid extends BaseHtmlElement /** @var DateTime */ protected $end; - protected $mode; + /** @var StdClass */ + private $stepExtraCounts; /** * Create a new calendar @@ -121,7 +123,10 @@ protected function createGrid(): BaseHtmlElement protected function assembleGrid(BaseHtmlElement $grid): void { $url = $this->calendar->getAddEntryUrl(); + $this->stepExtraCounts = new stdClass(); foreach ($this->createGridSteps() as $gridStep) { +// $count = $this->getGridExtraCount($gridStep); + $step = new HtmlElement( 'div', Attributes::create([ @@ -137,6 +142,17 @@ protected function assembleGrid(BaseHtmlElement $grid): void $content = $step; } + $stepDate = $gridStep->format('Y-m-d'); + $this->stepExtraCounts->{$stepDate} = new Link( + null, + null, + [ + 'target' => '_self', + 'hidden' => true + ] + ); + + $step->addHtml($this->stepExtraCounts->{$stepDate}); $this->assembleGridStep($content, $gridStep); $grid->addHtml($step); @@ -221,10 +237,7 @@ protected function assembleGridOverlay(BaseHtmlElement $overlay): void foreach ($competingOccupiers as $otherId) { list($otherRowStart, $otherRowSpan) = $rowPlacements[$otherId][$row]; - if ($this->mode === 'day') { - $rowStart += $otherRowSpan; - $rowPlacements[$otherId][$row] = [$otherRowStart, $otherRowSpan]; - } elseif ($otherRowStart === $rowStart) { + if ($otherRowStart === $rowStart) { $otherRowSpan = (int) ceil($otherRowSpan / 2); $rowStart += $otherRowSpan; $rowSpan -= $otherRowSpan; @@ -241,7 +254,6 @@ protected function assembleGridOverlay(BaseHtmlElement $overlay): void } $extraEntriesCount = []; - $removedEntry = []; foreach ($occupiedCells as $entry) { $continuation = false; $rows = $occupiedCells->getInfo(); @@ -254,8 +266,20 @@ protected function assembleGridOverlay(BaseHtmlElement $overlay): void $gridArea = $this->getGridArea($rowStart, $rowEnd, $colStart, $colEnd); $entryClass = 'area-' . implode('-', $gridArea); - if ($this->mode !== 'day' && $rowStart > $row + $sectionsPerStep) { - $this->updateExtraEntriesCount($gridArea, $extraEntriesCount, $removedEntry); + if ($rowStart > $row + $sectionsPerStep) { + $stepCol = $gridArea[1] - 1; + $stepRow = $rowStart - $this->getSectionsPerStep(); + $hourEnd = max($hours); + do { + $stepDate = $this->getStepDate($stepRow, $stepCol); + if (! isset($extraEntriesCount[$stepDate])) { + $extraEntriesCount[$stepDate] = 1; + } else { + $extraEntriesCount[$stepDate] += 1; + } + + $stepCol += 48; + } while ($hourEnd > 47 && $stepCol < $hourEnd); continue; } @@ -280,49 +304,31 @@ protected function assembleGridOverlay(BaseHtmlElement $overlay): void $this->assembleEntry($entryHtml, $entry, $continuation); $overlay->addHtml($entryHtml); - if ($this->mode !== 'day' && $rowStart === $row + $sectionsPerStep) { - $this->removeRowLastEntry( - $gridArea, - $entryHtml, - $removedEntry, - $extraEntriesCount - ); - } - $continuation = true; } } - foreach ($extraEntriesCount as $dayOffset => $count) { - $start = clone $this->getGridStart(); - $start->add(new DateInterval("P$dayOffset" . "D")); - - $countStyle = [ - 'grid-row-start' => $removedEntry[$dayOffset][1], - 'grid-column-start' => $removedEntry[$dayOffset][2], - ]; - $style->add(".additional-$dayOffset", $countStyle); - $entryHtml = new HtmlElement( - 'div', - Attributes::create( - [ - 'class' => ['entry-count', "additional-$dayOffset"] - ] - ), - new Link( + foreach ($extraEntriesCount as $date => $count) { + /** @var Link $stepCountLink */ + $stepCountLink = $this->stepExtraCounts->{$date}; + $stepCountLink->setAttribute('hidden', false); + $stepCountLink->setContent( + $this->translatePlural( + "+$count entry", "+$count entries", + $count + ) + ); + $stepCountLink + ->setUrl( Url::fromPath( 'notifications/schedules', [ 'mode' => 'day', - 'day' => $start->format('Y-m-d') + 'day' => $date ] - ), - ['target' => '_self'] - ) - ); - - $overlay->addHtml($entryHtml); + ) + ); } } @@ -394,4 +400,9 @@ protected function roundToNearestThirtyMinute(DateTime $time): DateTime return $time; } + + private function getGridExtraCount($gridStep) + { + return $this->stepExtraCounts[$gridStep]; + } } diff --git a/library/Notifications/Widget/Calendar/DayGrid.php b/library/Notifications/Widget/Calendar/DayGrid.php index 9ca070d0a..4c754e313 100644 --- a/library/Notifications/Widget/Calendar/DayGrid.php +++ b/library/Notifications/Widget/Calendar/DayGrid.php @@ -14,13 +14,16 @@ class DayGrid extends BaseGrid { - protected $mode = 'day'; - public function setGridStart(DateTime $start): BaseGrid { return parent::setGridStart($start); } + protected function getMaximumRowSpan(): int + { + return 28; + } + protected function calculateGridEnd(): DateTime { return (clone $this->getGridStart())->add(new DateInterval('P1D')); @@ -119,4 +122,9 @@ protected function removeRowLastEntry( array &$extraEntriesCount ): void { } + + protected function getStepDate(int $row, int $col): string + { + return $this->getGridStart()->format('Y-m-d'); + } } diff --git a/library/Notifications/Widget/Calendar/MonthGrid.php b/library/Notifications/Widget/Calendar/MonthGrid.php index 7280bf3fe..428e99279 100644 --- a/library/Notifications/Widget/Calendar/MonthGrid.php +++ b/library/Notifications/Widget/Calendar/MonthGrid.php @@ -15,8 +15,6 @@ class MonthGrid extends BaseGrid { - protected $mode = 'month'; - public function setGridStart(DateTime $start): BaseGrid { if ($start->format('j:H:i:s') !== '1:00:00:00') { @@ -65,6 +63,11 @@ protected function getColumnSpan() return 48; } + protected function getGridStep(int $row, int $col) + { + return intval($row / $this->getSectionsPerStep() + $col / $this->getColumnSpan()); + } + protected function getGridArea(int $rowStart, int $rowEnd, int $colStart, int $colEnd): array { return [$rowStart, $colStart, $rowEnd, $colEnd]; @@ -149,6 +152,15 @@ protected function getDaysOffset(int $row, int $col): int return (intval($row / $this->getSectionsPerStep())) * 7 + intval($col / 48); } + protected function getStepDate(int $row, int $col): string + { + $start = clone $this->getGridStart(); + $offset = intval($row / $this->getSectionsPerStep()) * 7 + intval($col / 48); + return $start + ->add(new DateInterval("P$offset" . 'D')) + ->format('Y-m-d'); + } + protected function updateExtraEntriesCount(array $gridArea, array &$extraEntriesCount, array &$removedEntry): void { $day = $this->getDaysOffset($gridArea[0], $gridArea[1]); diff --git a/library/Notifications/Widget/Calendar/Util.php b/library/Notifications/Widget/Calendar/Util.php index 3245bd926..7730638b2 100644 --- a/library/Notifications/Widget/Calendar/Util.php +++ b/library/Notifications/Widget/Calendar/Util.php @@ -18,7 +18,7 @@ public static function diffHours(DateTime $from, DateTime $to) } if ($diff->i > 0) { - $hours += $diff->i / 60; + $hours += (int) floor($diff->i / 60); } if ($diff->days > 0) { diff --git a/library/Notifications/Widget/Calendar/WeekGrid.php b/library/Notifications/Widget/Calendar/WeekGrid.php index 5e0402d58..afc6c7037 100644 --- a/library/Notifications/Widget/Calendar/WeekGrid.php +++ b/library/Notifications/Widget/Calendar/WeekGrid.php @@ -18,8 +18,6 @@ class WeekGrid extends BaseGrid { - protected $mode = 'week'; - public function setGridStart(DateTime $start): BaseGrid { if ($start->format('w:H:i:s') !== '1:00:00:00') { @@ -39,6 +37,11 @@ protected function getNoOfVisuallyConnectedHours(): int return 24; } + protected function getNumOfDays() + { + return 1; + } + protected function getGridArea(int $rowStart, int $rowEnd, int $colStart, int $colEnd): array { return [$colStart, $rowStart, $colEnd, $rowEnd]; @@ -138,6 +141,15 @@ protected function getDaysOffset(int $col): int return intval($col / 4) - 1; } + protected function getStepDate(int $row, int $col): string + { + $start = clone $this->getGridStart(); + $offset = intval($row / 4); + return $start + ->add(new DateInterval("P$offset" . 'D')) + ->format('Y-m-d'); + } + protected function updateExtraEntriesCount(array $gridArea, array &$extraEntriesCount, array &$removedEntry): void { $day = $this->getDaysOffset($gridArea[1]);