Skip to content

Commit

Permalink
Show extra appointments link for week and month views
Browse files Browse the repository at this point in the history
  • Loading branch information
raviks789 committed Oct 16, 2023
1 parent 578cb39 commit 667137f
Show file tree
Hide file tree
Showing 8 changed files with 287 additions and 48 deletions.
20 changes: 19 additions & 1 deletion library/Notifications/Widget/Calendar.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ class Calendar extends BaseHtmlElement
/** @var Url */
protected $addEntryUrl;

/** @var Url */
protected $dayViewUrl;

public function setControls(Controls $controls): self
{
$this->controls = $controls;
Expand Down Expand Up @@ -79,6 +82,19 @@ public function getAddEntryUrl(): ?Url
return $this->addEntryUrl;
}

public function setDayViewUrl(?Url $url): self
{
$this->dayViewUrl = $url;

return $this;
}

public function getDayViewUrl(string $date): ?Url
{
$url = clone $this->dayViewUrl;
return $url->setParam('day', $date);
}

protected function getModeStart(): DateTime
{
switch ($this->getControls()->getViewMode()) {
Expand All @@ -91,7 +107,9 @@ protected function getModeStart(): DateTime

return (new DateTime())->setTimestamp(strtotime($week));
default:
return DateTime::createFromFormat('Y-m-d', $this->getControls()->getValue('day'));
$day = $this->getControls()->getValue('day') ?: (new DateTime())->format('Y-m-d');

return DateTime::createFromFormat('Y-m-d H:i:s', $day . ' 00:00:00');
}
}

Expand Down
71 changes: 66 additions & 5 deletions library/Notifications/Widget/Calendar/BaseGrid.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Icinga\Module\Notifications\Widget\Calendar;

use DateInterval;
use DateTime;
use DateTimeInterface;
use Icinga\Module\Notifications\Widget\Calendar;
Expand Down Expand Up @@ -35,6 +36,9 @@ abstract class BaseGrid extends BaseHtmlElement
/** @var DateTime */
protected $end;

/** @var array Extra counts stored as [date1 => count1, date2 => count2]*/
protected $extraEntriesCount = [];

/**
* Create a new calendar
*
Expand Down Expand Up @@ -73,6 +77,13 @@ abstract protected function calculateGridEnd(): DateTime;

abstract protected function getNoOfVisuallyConnectedHours(): int;

/**
* Get Number of days in the grid
*
* @return int
*/
abstract protected function getNoOfDays(): int;

abstract protected function getGridArea(int $rowStart, int $rowEnd, int $colStart, int $colEnd): array;

protected function getSectionsPerStep(): int
Expand Down Expand Up @@ -137,6 +148,18 @@ protected function createGridOverlay(): BaseHtmlElement
return $overlay;
}

/**
* Fetch the count of additional number of entries for the given date
*
* @param string $date
*
* @return int
*/
public function getExtraEntryCount(string $date): int
{
return $this->extraEntriesCount[$date] ?? 0;
}

protected function assembleGridOverlay(BaseHtmlElement $overlay): void
{
$style = (new Style())->setNonce(Csp::getStyleNonce());
Expand Down Expand Up @@ -218,23 +241,39 @@ protected function assembleGridOverlay(BaseHtmlElement $overlay): void
}
}

$this->extraEntriesCount = [];
foreach ($occupiedCells as $entry) {
$continuation = false;
$rows = $occupiedCells->getInfo();
foreach ($rows as $row => $hours) {
list($rowStart, $rowSpan) = $rowPlacements[spl_object_id($entry)][$row];
if ($rowStart > $row + $sectionsPerStep) {
// TODO: Register as +1
continue;
}

$rowEnd = $rowStart + $rowSpan;
$colStart = min($hours) + 1;
$colEnd = max($hours) + 2;

$gridArea = $this->getGridArea($rowStart, $rowEnd, $colStart, $colEnd);
$entryClass = 'area-' . implode('-', $gridArea);

// Calculate number of entries that are not displayed in the grid for each date
if ($rowStart > $row + $sectionsPerStep) {
$stepRow = $rowStart - $this->getSectionsPerStep();
$startOffset = $this->getStepOffset($stepRow, $gridArea[1] - 1);
$endOffset = $this->getStepOffset($stepRow, $gridArea[3] - 2);
$startDate = (clone $this->getGridStart())->add(new DateInterval("P$startOffset" . 'D'));
$duration = $endOffset - $startOffset;
for ($i = 0; $i <= $duration; $i++) {
$startDate->add(new DateInterval("P$i" . 'D'));
$countIdx = $startDate->format('Y-m-d');
if (! isset($this->extraEntriesCount[$countIdx])) {
$this->extraEntriesCount[$countIdx] = 1;
} else {
$this->extraEntriesCount[$countIdx] += 1;
}
}

continue;
}

$style->add(".$entryClass", [
'grid-area' => sprintf('~"%d / %d / %d / %d"', ...$gridArea),
'background-color' => $entry->getAttendee()->getColor() . dechex((int) (256 * 0.1)),
Expand Down Expand Up @@ -328,4 +367,26 @@ protected function roundToNearestThirtyMinute(DateTime $time): DateTime

return $time;
}

/**
* Calculate offset of the day in the grid from given row and column
*
* @param int $row
* @param int $col
*
* @return int Offset of the day from grid start
*/
protected function getStepOffset(int $row, int $col): int
{
$days = $this->getNoOfDays();

switch ($days) {
case 7: // step offset for week mode
return intval($row / 4);
case 42: // step offset for month mode
return intval($row / $this->getSectionsPerStep()) * 7 + intval($col / 48);
default: // step offset for day mode
return 0;
}
}
}
19 changes: 16 additions & 3 deletions library/Notifications/Widget/Calendar/DayGrid.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use DateInterval;
use DateTime;
use InvalidArgumentException;
use ipl\Html\Attributes;
use ipl\Html\BaseHtmlElement;
use ipl\Html\HtmlElement;
Expand All @@ -14,13 +15,20 @@

class DayGrid extends BaseGrid
{
protected $mode = 'day';

public function setGridStart(DateTime $start): BaseGrid
{
if ($start->format('H:i:s') !== '00:00:00') {
throw new InvalidArgumentException('Start is not midnight');
}

return parent::setGridStart($start);
}

protected function getMaximumRowSpan(): int
{
return 28;
}

protected function calculateGridEnd(): DateTime
{
return (clone $this->getGridStart())->add(new DateInterval('P1D'));
Expand All @@ -31,6 +39,11 @@ protected function getNoOfVisuallyConnectedHours(): int
return 24;
}

protected function getNoOfDays(): int
{
return 1;
}

protected function getGridArea(int $rowStart, int $rowEnd, int $colStart, int $colEnd): array
{
return [$colStart, $rowStart, $colEnd, $rowEnd];
Expand Down Expand Up @@ -59,7 +72,7 @@ protected function createHeader(): BaseHtmlElement
new HtmlElement(
'span',
Attributes::create(['class' => 'day-name']),
Text::create($this->getGridStart()->format('D'))
Text::create($currentDay->format('D'))
),
new HtmlElement(
'span',
Expand Down
63 changes: 63 additions & 0 deletions library/Notifications/Widget/Calendar/ExtraEntryCount.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?php

namespace Icinga\Module\Notifications\Widget\Calendar;

use ipl\I18n\Translation;
use ipl\Web\Url;
use ipl\Web\Widget\Link;

class ExtraEntryCount extends Link
{
use Translation;

protected $defaultAttributes = ['class' => 'extra-count'];

/** @var ?Url Url to the day grid*/
protected $url;

/** @var BaseGrid */
protected $grid;

/** @var string Date in Y-m-d format */
protected $date;

/**
* Grid setter
*
* @param BaseGrid $grid
*
* @return $this
*/
public function setGrid(BaseGrid $grid): self
{
$this->grid = $grid;

return $this;
}

/**
* Setter for Date
*
* @param string $date Date in Y-m-d format
*
* @return $this
*/
public function setDate(string $date): self
{
$this->date = $date;

return $this;
}

protected function assemble()
{
$count = $this->grid->getExtraEntryCount($this->date);
if ($count > 0) {
$this->setContent($this->translatePlural(
"+$count entry",
"+$count entries",
$count
));
}
}
}
12 changes: 12 additions & 0 deletions library/Notifications/Widget/Calendar/MonthGrid.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ public function setGridStart(DateTime $start): BaseGrid
return parent::setGridStart($start);
}

protected function getNoOfDays(): int
{
return 42;
}

protected function calculateGridEnd(): DateTime
{
return (clone $this->getGridStart())->add(new DateInterval('P42D'));
Expand All @@ -36,6 +41,13 @@ protected function calculateGridEnd(): DateTime
protected function assembleGridStep(BaseHtmlElement $content, DateTime $step): void
{
$content->addHtml(Text::create($step->format('j')));

$dayViewUrl = $this->calendar->getDayViewUrl($step->format('Y-m-d'));
$content->addHtml(
(new ExtraEntryCount(null, $dayViewUrl, ['target' => '_self']))
->setGrid($this)
->setDate($step->format('Y-m-d'))
);
}

protected function getRowStartModifier(): int
Expand Down
17 changes: 17 additions & 0 deletions library/Notifications/Widget/Calendar/WeekGrid.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ protected function getNoOfVisuallyConnectedHours(): int
return 24;
}

protected function getNoOfDays(): int
{
return 7;
}

protected function getGridArea(int $rowStart, int $rowEnd, int $colStart, int $colEnd): array
{
return [$colStart, $rowStart, $colEnd, $rowEnd];
Expand Down Expand Up @@ -116,6 +121,18 @@ protected function createSidebar(): BaseHtmlElement
return $sidebar;
}

protected function assembleGridStep(BaseHtmlElement $content, DateTime $step): void
{
if ($step->format('H') === '23') {
$dayViewUrl = $this->calendar->getDayViewUrl($step->format('Y-m-d'));
$content->addHtml(
(new ExtraEntryCount(null, $dayViewUrl, ['target' => '_self']))
->setGrid($this)
->setDate($step->format('Y-m-d'))
);
}
}

protected function assemble()
{
$this->getAttributes()->add('class', 'week');
Expand Down
Loading

0 comments on commit 667137f

Please sign in to comment.