From 22cb8d6aaa281e097634af68515dd10162fc475d Mon Sep 17 00:00:00 2001 From: raviks789 Date: Thu, 13 Jun 2024 13:58:49 +0200 Subject: [PATCH] Preview schedules in the overview --- .../controllers/ScheduleController.php | 4 + .../Widget/ItemList/ScheduleListItem.php | 21 +++++- library/Notifications/Widget/Timeline.php | 74 +++++++++++++++---- public/css/list/schedule-list.less | 19 +++++ 4 files changed, 101 insertions(+), 17 deletions(-) create mode 100644 public/css/list/schedule-list.less diff --git a/application/controllers/ScheduleController.php b/application/controllers/ScheduleController.php index 8d16d7d68..4e3cfac0e 100644 --- a/application/controllers/ScheduleController.php +++ b/application/controllers/ScheduleController.php @@ -154,14 +154,17 @@ public function editRotationAction(): void $form->setSuggestionUrl(Url::fromPath('notifications/schedule/suggest-recipient')); $form->on(RotationConfigForm::ON_SUCCESS, function (RotationConfigForm $form) use ($id, $scheduleId) { $form->editRotation($id); + $this->sendExtraUpdates(['#col1']); $this->closeModalAndRefreshRelatedView(Links::schedule($scheduleId)); }); $form->on(RotationConfigForm::ON_SENT, function (RotationConfigForm $form) use ($id, $scheduleId) { if ($form->hasBeenRemoved()) { $form->removeRotation($id); + $this->sendExtraUpdates(['#col1']); $this->closeModalAndRefreshRelatedView(Links::schedule($scheduleId)); } elseif ($form->hasBeenWiped()) { $form->wipeRotation(); + $this->sendExtraUpdates(['#col1']); $this->closeModalAndRefreshRelatedView(Links::schedule($scheduleId)); } elseif (! $form->hasBeenSubmitted()) { foreach ($form->getPartUpdates() as $update) { @@ -188,6 +191,7 @@ public function moveRotationAction(): void $form = new MoveRotationForm(Database::get()); $form->on(MoveRotationForm::ON_SUCCESS, function (MoveRotationForm $form) { + $this->sendExtraUpdates(['#col1']); $this->redirectNow(Links::schedule($form->getScheduleId())); }); diff --git a/library/Notifications/Widget/ItemList/ScheduleListItem.php b/library/Notifications/Widget/ItemList/ScheduleListItem.php index 24e9f9d80..d0b80f293 100644 --- a/library/Notifications/Widget/ItemList/ScheduleListItem.php +++ b/library/Notifications/Widget/ItemList/ScheduleListItem.php @@ -4,10 +4,15 @@ namespace Icinga\Module\Notifications\Widget\ItemList; +use DateTime; use Icinga\Module\Notifications\Common\Links; use Icinga\Module\Notifications\Model\Schedule; +use Icinga\Module\Notifications\Widget\Timeline; +use Icinga\Module\Notifications\Widget\Timeline\Rotation; +use Icinga\Util\Csp; use ipl\Html\BaseHtmlElement; use ipl\Web\Common\BaseListItem; +use ipl\Web\Style; use ipl\Web\Widget\Link; /** @@ -43,6 +48,20 @@ protected function assembleHeader(BaseHtmlElement $header): void protected function assembleMain(BaseHtmlElement $main): void { - $main->addHtml($this->createHeader()); + // Number of days is set to 7, since default mode for schedule is week + // and the start day should be the current day + $timeline = (new Timeline((new DateTime())->setTime(0, 0), 7)) + ->setIgnoreRotations() + ->setStyle( + (new Style()) + ->setNonce(Csp::getStyleNonce()) + ->setModule('notifications') + ); + + foreach ($this->item->rotation->with('timeperiod')->orderBy('first_handoff', SORT_DESC) as $rotation) { + $timeline->addRotation(new Rotation($rotation)); + } + + $main->addHtml($this->createHeader(), $timeline); } } diff --git a/library/Notifications/Widget/Timeline.php b/library/Notifications/Widget/Timeline.php index 6ca486df8..a1591ea71 100644 --- a/library/Notifications/Widget/Timeline.php +++ b/library/Notifications/Widget/Timeline.php @@ -47,6 +47,9 @@ class Timeline extends BaseHtmlElement implements EntryProvider /** @var ?DynamicGrid */ protected $grid; + /** @var bool Whether to ignore creating rotations */ + protected $ignoreRotations = false; + /** * Set the style object to register inline styles in * @@ -87,6 +90,30 @@ public function __construct(DateTime $start, int $days) $this->days = $days; } + /** + * Set whether creating rotations should be ignored + * + * @param bool $ignoreRotations + * + * @return $this + */ + public function setIgnoreRotations(bool $ignoreRotations = true): self + { + $this->ignoreRotations = $ignoreRotations; + + return $this; + } + + /** + * Get whether creating rotations should be ignored + * + * @return bool + */ + public function getIgnoreRotations(): bool + { + return $this->ignoreRotations; + } + /** * Add a rotation to the timeline * @@ -145,13 +172,22 @@ public function getEntries(): Traversable }, 0); $occupiedCells = []; - $resultPosition = $maxPriority + 1; + + $ignoreRotations = $this->getIgnoreRotations(); + if ($ignoreRotations) { + $resultPosition = 0; + } else { + $resultPosition = $maxPriority + 1; + } + foreach ($rotations as $rotation) { $rotationPosition = $maxPriority - $rotation->getPriority(); foreach ($rotation->fetchTimeperiodEntries($this->start, $this->getGrid()->getGridEnd()) as $entry) { $entry->setPosition($rotationPosition); - yield $entry; + if (! $ignoreRotations) { + yield $entry; + } $occupiedCells += $getDesiredCells($entry); } @@ -221,15 +257,17 @@ protected function getGrid(): DynamicGrid $this->grid = new DynamicGrid($this, $this->getStyle(), $this->start); $this->grid->setDays($this->days); - $rotations = $this->rotations; - usort($rotations, function (Rotation $a, Rotation $b) { - return $b->getPriority() <=> $a->getPriority(); - }); - $occupiedPriorities = []; - foreach ($rotations as $rotation) { - if (! isset($occupiedPriorities[$rotation->getPriority()])) { - $occupiedPriorities[$rotation->getPriority()] = true; - $this->grid->addToSideBar($this->assembleSidebarEntry($rotation)); + if (! $this->getIgnoreRotations()) { + $rotations = $this->rotations; + usort($rotations, function (Rotation $a, Rotation $b) { + return $b->getPriority() <=> $a->getPriority(); + }); + $occupiedPriorities = []; + foreach ($rotations as $rotation) { + if (! isset($occupiedPriorities[$rotation->getPriority()])) { + $occupiedPriorities[$rotation->getPriority()] = true; + $this->grid->addToSideBar($this->assembleSidebarEntry($rotation)); + } } } } @@ -259,6 +297,11 @@ protected function assembleSidebarEntry(Rotation $rotation): BaseHtmlElement protected function assemble() { + $this->addHtml( + $this->getGrid(), + $this->getStyle() + ); + if (empty($this->rotations)) { $this->getGrid()->addToSideBar( new HtmlElement( @@ -267,6 +310,10 @@ protected function assemble() Text::create($this->translate('No rotations configured')) ) ); + + if ($this->getIgnoreRotations()) { + return; + } } $this->getGrid()->addToSideBar( @@ -276,10 +323,5 @@ protected function assemble() Text::create($this->translate('Result')) ) ); - - $this->addHtml( - $this->getGrid(), - $this->getStyle() - ); } } diff --git a/public/css/list/schedule-list.less b/public/css/list/schedule-list.less new file mode 100644 index 000000000..f6897e24e --- /dev/null +++ b/public/css/list/schedule-list.less @@ -0,0 +1,19 @@ +/* Icinga Notifications Web | (c) 2024 Icinga GmbH | GPLv2 */ +.item-list.schedule-list { + .list-item { + .main { + .header { + background: none; + } + + .entry { + pointer-events: none; + } + } + + .timeline { + margin-left: 5em; + height: auto; + } + } +}