Skip to content

Commit

Permalink
Show extra appointments link for more than 4 appointments in a day
Browse files Browse the repository at this point in the history
  • Loading branch information
raviks789 committed Sep 28, 2023
1 parent 7909bf0 commit 218f0f3
Show file tree
Hide file tree
Showing 4 changed files with 217 additions and 6 deletions.
84 changes: 78 additions & 6 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 All @@ -14,6 +15,7 @@
use ipl\Html\Text;
use ipl\I18n\Translation;
use ipl\Web\Style;
use ipl\Web\Url;
use ipl\Web\Widget\Link;
use SplObjectStorage;
use Traversable;
Expand All @@ -35,6 +37,8 @@ abstract class BaseGrid extends BaseHtmlElement
/** @var DateTime */
protected $end;

protected $mode;

/**
* Create a new calendar
*
Expand Down Expand Up @@ -75,6 +79,19 @@ abstract protected function getNoOfVisuallyConnectedHours(): int;

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

abstract protected function updateExtraEntriesCount(
array $gridArea,
array &$extraEntriesCount,
array &$removedEntry
): void;

abstract protected function removeRowLastEntry(
array $gridArea,
BaseHtmlElement $entryHtml,
array &$removedEntry,
array &$extraEntriesCount
): void;

protected function getSectionsPerStep(): int
{
return $this->getMaximumRowSpan();
Expand Down Expand Up @@ -202,7 +219,10 @@ protected function assembleGridOverlay(BaseHtmlElement $overlay): void

foreach ($competingOccupiers as $otherId) {
list($otherRowStart, $otherRowSpan) = $rowPlacements[$otherId][$row];
if ($otherRowStart === $rowStart) {
if ($this->mode === 'day') {
$rowStart += $otherRowSpan;
$rowPlacements[$otherId][$row] = [$otherRowStart, $otherRowSpan];
} elseif ($otherRowStart === $rowStart) {
$otherRowSpan = (int) ceil($otherRowSpan / 2);
$rowStart += $otherRowSpan;
$rowSpan -= $otherRowSpan;
Expand All @@ -218,23 +238,26 @@ protected function assembleGridOverlay(BaseHtmlElement $overlay): void
}
}

$extraEntriesCount = [];
$removedEntry = [];
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);

if ($this->mode !== 'day' && $rowStart > $row + $sectionsPerStep) {
$this->updateExtraEntriesCount($gridArea, $extraEntriesCount, $removedEntry);

continue;
}

$style->add(".$entryClass", [
'grid-area' => sprintf('~"%d / %d / %d / %d"', ...$gridArea),
'background-color' => $entry->getAttendee()->getColor() . dechex((int) (256 * 0.1)),
Expand All @@ -255,9 +278,58 @@ 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"));
if ($count === 0) {
continue;
} elseif ($removedEntry[$dayOffset][0] !== null) {
$overlay->remove($removedEntry[$dayOffset][0]);
}

$countStyle = [
'grid-row-start' => $removedEntry[$dayOffset][1],
'grid-column-start' => $removedEntry[$dayOffset][2],
'pointer-events' => 'all',
'text-align' => 'end',
'margin-right' => '0.2em'
];
$style->add(".additional-$dayOffset", $countStyle);
$entryHtml = new HtmlElement(
'div',
Attributes::create(
[
'class' => ["additional-$dayOffset"]
]
),
new Link(
"+$count",
Url::fromPath(
'notifications/schedules',
[
'mode' => 'day',
'day' => $start->format('Y-m-d')
]
),
['target' => '_self']
)
);

$overlay->addHtml($entryHtml);
}
}

protected function assembleEntry(BaseHtmlElement $html, Entry $entry, bool $isContinuation): void
Expand Down
12 changes: 12 additions & 0 deletions library/Notifications/Widget/Calendar/DayGrid.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,4 +107,16 @@ protected function assemble()
$this->createGridOverlay()
);
}

protected function updateExtraEntriesCount(array $gridArea, array &$extraEntriesCount, array &$removedEntry): void
{
}

protected function removeRowLastEntry(
array $gridArea,
BaseHtmlElement $entryHtml,
array &$removedEntry,
array &$extraEntriesCount
): void {
}
}
88 changes: 88 additions & 0 deletions library/Notifications/Widget/Calendar/MonthGrid.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@

class MonthGrid extends BaseGrid
{
protected $mode = 'month';

public function setGridStart(DateTime $start): BaseGrid
{
if ($start->format('j:H:i:s') !== '1:00:00:00') {
Expand Down Expand Up @@ -53,6 +55,16 @@ protected function getNoOfVisuallyConnectedHours(): int
return 7 * 24;
}

protected function getNumOfColumns()
{
return 7 * 48;
}

protected function getColumnSpan()
{
return 48;
}

protected function getGridArea(int $rowStart, int $rowEnd, int $colStart, int $colEnd): array
{
return [$rowStart, $colStart, $rowEnd, $colEnd];
Expand Down Expand Up @@ -131,4 +143,80 @@ protected function assemble()
$this->createGridOverlay()
);
}

protected function getDaysOffset(int $row, int $col): int
{
return (intval($row / $this->getSectionsPerStep()) - 1) * 7 + intval($col / 48);
}

protected function updateExtraEntriesCount(array $gridArea, array &$extraEntriesCount, array &$removedEntry): void
{
$day = $this->getDaysOffset($gridArea[0], $gridArea[1]);
$startDay = $day;

$colSpan = $this->getColumnSpan();
$endDay = $this->getDaysOffset($gridArea[2], $gridArea[3]);
while (($endDay - $startDay) >= 0) {
$col = $gridArea[1] + ($startDay - $day) * $colSpan;
if ($startDay !== $day && $col > $this->getNumOfColumns()) {
break;
}

if (! isset($extraEntriesCount[$startDay])) {
$removedEntry[$startDay] = [
null,
$gridArea[0] - 1,
(intval($col / $colSpan) + 1) * $colSpan - 3
];

$extraEntriesCount[$startDay] = 1;
} elseif ($extraEntriesCount[$startDay] === 0) {
$extraEntriesCount[$startDay] += 2;
} else {
$extraEntriesCount[$startDay] += 1;
}

$startDay += 1;
}
}

protected function removeRowLastEntry(
array $gridArea,
BaseHtmlElement $entryHtml,
array &$removedEntry,
array &$extraEntriesCount
): void {
$day = $this->getDaysOffset($gridArea[0], $gridArea[1]);
$startDay = $day;

$colSpan = $this->getColumnSpan();
$numCols = $this->getNumOfColumns();
$endDay = $this->getDaysOffset($gridArea[2], $gridArea[3]);
while (($endDay - $startDay) >= 0) {
$col = $gridArea[1] + ($startDay - $day) * $colSpan;

if ($startDay !== $day && $col > $numCols) {
$startDay += 1;
continue;
}

if ($startDay === $day) {
$removedEntry[$startDay] = [
$entryHtml,
$gridArea[0],
(intval($col / $colSpan) + 1) * $colSpan - 3
];
} else {
$removedEntry[$startDay] = [
null,
$gridArea[0],
(intval($col / $colSpan) + 1) * $colSpan - 3
];
}

$extraEntriesCount[$startDay] = 0;

$startDay += 1;
}
}
}
39 changes: 39 additions & 0 deletions library/Notifications/Widget/Calendar/WeekGrid.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,15 @@
use ipl\Html\BaseHtmlElement;
use ipl\Html\HtmlElement;
use ipl\Html\Text;
use ipl\Web\Style;
use ipl\Web\Url;
use ipl\Web\Widget\Link;
use Traversable;

class WeekGrid extends BaseGrid
{
protected $mode = 'week';

public function setGridStart(DateTime $start): BaseGrid
{
if ($start->format('w:H:i:s') !== '1:00:00:00') {
Expand Down Expand Up @@ -127,4 +132,38 @@ protected function assemble()
$this->createGridOverlay()
);
}

protected function getDaysOffset(int $col): int
{
return intval($col / 4) - 1;
}

protected function updateExtraEntriesCount(array $gridArea, array &$extraEntriesCount, array &$removedEntry): void
{
$day = $this->getDaysOffset($gridArea[1]);

if (! isset($extraEntriesCount[$day])) {
$extraEntriesCount[$day] = 1;
} elseif ($extraEntriesCount[$day] === 0) {
$extraEntriesCount[$day] += 2;
} else {
$extraEntriesCount[$day] += 1;
}
}

protected function removeRowLastEntry(
array $gridArea,
BaseHtmlElement $entryHtml,
array &$removedEntry,
array &$extraEntriesCount
): void {
$day = $this->getDaysOffset($gridArea[1]);
$removedEntry[$day] = [
$entryHtml,
2 * $this->getNoOfVisuallyConnectedHours(),
$gridArea[1]
];

$extraEntriesCount[$day] = 0;
}
}

0 comments on commit 218f0f3

Please sign in to comment.