diff --git a/application/controllers/ScheduleController.php b/application/controllers/ScheduleController.php index 8d16d7d68..24d5a142b 100644 --- a/application/controllers/ScheduleController.php +++ b/application/controllers/ScheduleController.php @@ -188,6 +188,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..3a4e73172 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,19 @@ 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, true); + $timeline->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..ceeda5a09 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 * @@ -80,11 +83,13 @@ public function getStyle(): Style * * @param DateTime $start The day the grid should start on * @param int $days Number of days to show on the grid + * @param bool $ignoreRotations Whether to ignore creating rotations */ - public function __construct(DateTime $start, int $days) + public function __construct(DateTime $start, int $days, $ignoreRotations = false) { $this->start = $start; $this->days = $days; + $this->ignoreRotations = $ignoreRotations; } /** @@ -145,13 +150,21 @@ public function getEntries(): Traversable }, 0); $occupiedCells = []; - $resultPosition = $maxPriority + 1; + + if ($this->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 (! $this->ignoreRotations) { + yield $entry; + } $occupiedCells += $getDesiredCells($entry); } @@ -221,15 +234,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->ignoreRotations) { + $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 +274,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 +287,10 @@ protected function assemble() Text::create($this->translate('No rotations configured')) ) ); + + if ($this->ignoreRotations) { + return; + } } $this->getGrid()->addToSideBar( @@ -276,10 +300,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..fd3b08430 --- /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; + } + } +} \ No newline at end of file