mirror of
https://github.com/Icinga/icingadb-web.git
synced 2026-02-19 02:27:57 -05:00
Introduce DowntimeRenderer
- Use it for ObjectList and ObjectHeader - Remove now unused code and css
This commit is contained in:
parent
c55f1dceb8
commit
c15f32a43f
13 changed files with 327 additions and 360 deletions
|
|
@ -10,7 +10,7 @@ use Icinga\Module\Icingadb\Common\Links;
|
|||
use Icinga\Module\Icingadb\Model\Downtime;
|
||||
use Icinga\Module\Icingadb\Web\Controller;
|
||||
use Icinga\Module\Icingadb\Widget\Detail\DowntimeDetail;
|
||||
use Icinga\Module\Icingadb\Widget\ItemList\DowntimeList;
|
||||
use Icinga\Module\Icingadb\Widget\Detail\ObjectHeader;
|
||||
use ipl\Stdlib\Filter;
|
||||
use ipl\Web\Url;
|
||||
|
||||
|
|
@ -61,11 +61,7 @@ class DowntimeController extends Controller
|
|||
{
|
||||
$detail = new DowntimeDetail($this->downtime);
|
||||
|
||||
$this->addControl((new DowntimeList([$this->downtime]))
|
||||
->setViewMode('minimal')
|
||||
->setDetailActionsDisabled()
|
||||
->setCaptionDisabled()
|
||||
->setNoSubjectLink());
|
||||
$this->addControl(new ObjectHeader($this->downtime));
|
||||
|
||||
$this->addContent($detail);
|
||||
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@ use Icinga\Module\Icingadb\Forms\Command\Object\DeleteDowntimeForm;
|
|||
use Icinga\Module\Icingadb\Model\Downtime;
|
||||
use Icinga\Module\Icingadb\Web\Control\SearchBar\ObjectSuggestions;
|
||||
use Icinga\Module\Icingadb\Web\Controller;
|
||||
use Icinga\Module\Icingadb\Widget\ItemList\DowntimeList;
|
||||
use Icinga\Module\Icingadb\Web\Control\ViewModeSwitcher;
|
||||
use Icinga\Module\Icingadb\Widget\ItemList\ObjectList;
|
||||
use Icinga\Module\Icingadb\Widget\ShowMore;
|
||||
use ipl\Web\Control\LimitControl;
|
||||
use ipl\Web\Control\SortControl;
|
||||
|
|
@ -87,7 +87,12 @@ class DowntimesController extends Controller
|
|||
|
||||
$results = $downtimes->execute();
|
||||
|
||||
$this->addContent((new DowntimeList($results))->setViewMode($viewModeSwitcher->getViewMode()));
|
||||
$this->addContent(
|
||||
(new ObjectList($results))
|
||||
->setViewMode($viewModeSwitcher->getViewMode())
|
||||
->setMultiselectUrl(Links::downtimesDetails())
|
||||
->setDetailUrl(Url::fromPath('icingadb/downtime'))
|
||||
);
|
||||
|
||||
if ($compact) {
|
||||
$this->addContent(
|
||||
|
|
@ -162,7 +167,7 @@ class DowntimesController extends Controller
|
|||
|
||||
$rs = $downtimes->execute();
|
||||
|
||||
$this->addControl((new DowntimeList($rs))->setViewMode('minimal'));
|
||||
$this->addControl((new ObjectList($rs))->setViewMode('minimal'));
|
||||
|
||||
$this->addControl(new ShowMore(
|
||||
$rs,
|
||||
|
|
|
|||
255
library/Icingadb/View/DowntimeRenderer.php
Normal file
255
library/Icingadb/View/DowntimeRenderer.php
Normal file
|
|
@ -0,0 +1,255 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2025 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\View;
|
||||
|
||||
use Icinga\Date\DateFormatter;
|
||||
use Icinga\Module\Icingadb\Common\HostLink;
|
||||
use Icinga\Module\Icingadb\Common\Icons;
|
||||
use Icinga\Module\Icingadb\Common\Links;
|
||||
use Icinga\Module\Icingadb\Common\ServiceLink;
|
||||
use Icinga\Module\Icingadb\Common\TicketLinks;
|
||||
use Icinga\Module\Icingadb\Model\Downtime;
|
||||
use Icinga\Module\Icingadb\Widget\MarkdownLine;
|
||||
use ipl\Html\Attributes;
|
||||
use ipl\Html\Html;
|
||||
use ipl\Html\HtmlDocument;
|
||||
use ipl\Html\HtmlElement;
|
||||
use ipl\Html\TemplateString;
|
||||
use ipl\Html\Text;
|
||||
use ipl\I18n\Translation;
|
||||
use ipl\Web\Common\ItemRenderer;
|
||||
use ipl\Web\Widget\Icon;
|
||||
use ipl\Web\Widget\Link;
|
||||
|
||||
/** @implements ItemRenderer<Downtime> */
|
||||
class DowntimeRenderer implements ItemRenderer
|
||||
{
|
||||
use Translation;
|
||||
use TicketLinks;
|
||||
use HostLink;
|
||||
use ServiceLink;
|
||||
|
||||
/** @var int Current Time */
|
||||
protected $currentTime;
|
||||
|
||||
/** @var int Duration */
|
||||
protected $duration;
|
||||
|
||||
/** @var int Downtime end time */
|
||||
protected $endTime;
|
||||
|
||||
/** @var bool Whether the downtime is active */
|
||||
protected $isActive;
|
||||
|
||||
/** @var int Downtime start time */
|
||||
protected $startTime;
|
||||
|
||||
/** @var bool Whether the state has been loaded */
|
||||
protected $stateLoaded = false;
|
||||
|
||||
/**
|
||||
* @var bool Whether the item is being rendered in the detail view of the associated object (host/service)
|
||||
*
|
||||
* When true:
|
||||
*
|
||||
* - Creation of the link of the associated object (host/service) is omitted from the title
|
||||
* - The ticket link will be created
|
||||
*/
|
||||
protected $isDetailView = false;
|
||||
|
||||
/**
|
||||
* Set whether the item is being rendered in the detail view of the associated object (host/service)
|
||||
*
|
||||
* @param bool $state
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setIsDetailView(bool $state = true): self
|
||||
{
|
||||
$this->isDetailView = $state;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the state of the downtime
|
||||
*
|
||||
* @param Downtime $item
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function loadState(Downtime $item): void
|
||||
{
|
||||
if ($this->stateLoaded) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
isset($item->start_time, $item->end_time)
|
||||
&& $item->is_flexible
|
||||
&& $item->is_in_effect
|
||||
) {
|
||||
$this->startTime = $item->start_time->getTimestamp();
|
||||
$this->endTime = $item->end_time->getTimestamp();
|
||||
} else {
|
||||
$this->startTime = $item->scheduled_start_time->getTimestamp();
|
||||
$this->endTime = $item->scheduled_end_time->getTimestamp();
|
||||
}
|
||||
|
||||
$this->currentTime = time();
|
||||
|
||||
$this->isActive = $item->is_in_effect
|
||||
|| ($item->is_flexible && $item->scheduled_start_time->getTimestamp() <= $this->currentTime);
|
||||
|
||||
$until = ($this->isActive ? $this->endTime : $this->startTime) - $this->currentTime;
|
||||
$this->duration = explode(' ', DateFormatter::formatDuration(
|
||||
$until <= 3600 ? $until : $until + (3600 - ((int) $until % 3600))
|
||||
), 2)[0];
|
||||
|
||||
$this->stateLoaded = true;
|
||||
}
|
||||
|
||||
public function assembleAttributes($item, Attributes $attributes, string $layout): void
|
||||
{
|
||||
$attributes->add(new Attributes(['class' => ['downtime', $item->is_in_effect ? 'in-effect' : '']]));
|
||||
}
|
||||
|
||||
public function assembleVisual($item, HtmlDocument $visual, string $layout): void
|
||||
{
|
||||
$this->loadState($item);
|
||||
|
||||
$dateTime = DateFormatter::formatDateTime($this->endTime);
|
||||
|
||||
if ($this->isActive) {
|
||||
$visual->addHtml(Html::sprintf(
|
||||
$this->translate('%s left', '<timespan>..'),
|
||||
Html::tag(
|
||||
'strong',
|
||||
Html::tag(
|
||||
'time',
|
||||
[
|
||||
'datetime' => $dateTime,
|
||||
'title' => $dateTime
|
||||
],
|
||||
$this->duration
|
||||
)
|
||||
)
|
||||
));
|
||||
} else {
|
||||
$visual->addHtml(Html::sprintf(
|
||||
$this->translate('in %s', '..<timespan>'),
|
||||
Html::tag('strong', $this->duration)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
public function assembleTitle($item, HtmlDocument $title, string $layout): void
|
||||
{
|
||||
if ($this->isDetailView) {
|
||||
$link = null;
|
||||
} elseif ($item->object_type === 'host') {
|
||||
$link = $this->createHostLink($item->host, true);
|
||||
} else {
|
||||
$link = $this->createServiceLink($item->service, $item->service->host, true);
|
||||
}
|
||||
|
||||
if ($item->is_flexible) {
|
||||
if ($link !== null) {
|
||||
$template = $this->translate('{{#link}}Flexible Downtime{{/link}} for %s');
|
||||
} else {
|
||||
$template = $this->translate('Flexible Downtime');
|
||||
}
|
||||
} else {
|
||||
if ($link !== null) {
|
||||
$template = $this->translate('{{#link}}Fixed Downtime{{/link}} for %s');
|
||||
} else {
|
||||
$template = $this->translate('Fixed Downtime');
|
||||
}
|
||||
}
|
||||
|
||||
if ($layout === 'header') {
|
||||
if ($link === null) {
|
||||
$title->addHtml(HtmlElement::create('span', [ 'class' => 'subject'], $template));
|
||||
} else {
|
||||
$title->addHtml(TemplateString::create(
|
||||
$template,
|
||||
['link' => HtmlElement::create('span', [ 'class' => 'subject'])],
|
||||
$link
|
||||
));
|
||||
}
|
||||
} else {
|
||||
if ($link === null) {
|
||||
$title->addHtml(new Link($template, Links::downtime($item)));
|
||||
} else {
|
||||
$title->addHtml(TemplateString::create(
|
||||
$template,
|
||||
['link' => new Link('', Links::downtime($item))],
|
||||
$link
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function assembleCaption($item, HtmlDocument $caption, string $layout): void
|
||||
{
|
||||
$markdownLine = new MarkdownLine(
|
||||
$this->isDetailView ? $this->createTicketLinks($item->comment) : $item->comment
|
||||
);
|
||||
$caption->getAttributes()->add($markdownLine->getAttributes());
|
||||
$caption->addHtml(
|
||||
new HtmlElement(
|
||||
'span',
|
||||
null,
|
||||
new Icon(Icons::USER),
|
||||
Text::create($item->author)
|
||||
),
|
||||
Text::create(': ')
|
||||
)->addFrom($markdownLine);
|
||||
}
|
||||
|
||||
public function assembleExtendedInfo($item, HtmlDocument $info, string $layout): void
|
||||
{
|
||||
$this->loadState($item);
|
||||
|
||||
$dateTime = DateFormatter::formatDateTime($this->isActive ? $this->endTime : $this->startTime);
|
||||
|
||||
$info->addHtml(Html::tag(
|
||||
'time',
|
||||
[
|
||||
'datetime' => $dateTime,
|
||||
'title' => $dateTime
|
||||
],
|
||||
sprintf(
|
||||
$this->isActive
|
||||
? $this->translate('expires in %s', '..<timespan>')
|
||||
: $this->translate('starts in %s', '..<timespan>'),
|
||||
$this->duration
|
||||
)
|
||||
));
|
||||
}
|
||||
|
||||
public function assembleFooter($item, HtmlDocument $footer, string $layout): void
|
||||
{
|
||||
}
|
||||
|
||||
public function assemble($item, string $name, HtmlDocument $element, string $layout): bool
|
||||
{
|
||||
if ($name === 'progress' && ($layout === 'detailed' || $layout === 'common')) {
|
||||
$this->loadState($item);
|
||||
|
||||
$element
|
||||
->addAttributes(Attributes::create([
|
||||
'data-animate-progress' => true,
|
||||
'data-start-time' => $this->startTime,
|
||||
'data-end-time' => $this->endTime
|
||||
]))
|
||||
->addHtml(new HtmlElement('div', Attributes::create(['class' => 'bar'])));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -10,12 +10,13 @@ use Icinga\Module\Icingadb\Common\Auth;
|
|||
use Icinga\Module\Icingadb\Common\Database;
|
||||
use Icinga\Module\Icingadb\Common\HostLink;
|
||||
use Icinga\Module\Icingadb\Common\Links;
|
||||
use Icinga\Module\Icingadb\Widget\ItemList\ObjectList;
|
||||
use Icinga\Module\Icingadb\Widget\MarkdownText;
|
||||
use Icinga\Module\Icingadb\Common\ServiceLink;
|
||||
use Icinga\Module\Icingadb\Forms\Command\Object\DeleteDowntimeForm;
|
||||
use Icinga\Module\Icingadb\Model\Downtime;
|
||||
use Icinga\Module\Icingadb\Widget\ItemList\DowntimeList;
|
||||
use Icinga\Module\Icingadb\Widget\ShowMore;
|
||||
use ipl\Web\Url;
|
||||
use ipl\Web\Widget\EmptyState;
|
||||
use ipl\Web\Widget\HorizontalKeyValue;
|
||||
use ipl\Html\BaseHtmlElement;
|
||||
|
|
@ -180,7 +181,9 @@ class DowntimeDetail extends BaseHtmlElement
|
|||
if ($children->hasResult()) {
|
||||
$this->addHtml(
|
||||
new HtmlElement('h2', null, Text::create(t('Children'))),
|
||||
new DowntimeList($children),
|
||||
(new ObjectList($children))
|
||||
->setMultiselectUrl(Links::downtimesDetails())
|
||||
->setDetailUrl(Url::fromPath('icingadb/downtime')),
|
||||
(new ShowMore($children, Links::downtimes()->setQueryString(
|
||||
QueryString::render(Filter::any(
|
||||
Filter::equal('downtime.parent.name', $this->downtime->name),
|
||||
|
|
|
|||
|
|
@ -285,7 +285,9 @@ class ObjectDetail extends BaseHtmlElement
|
|||
$content = [Html::tag('h2', t('Downtimes'))];
|
||||
|
||||
if ($downtimes->hasResult()) {
|
||||
$content[] = (new DowntimeList($downtimes))->setObjectLinkDisabled()->setTicketLinkEnabled();
|
||||
$content[] = (new TicketLinkObjectList($downtimes))
|
||||
->setMultiselectUrl(Links::downtimesDetails())
|
||||
->setDetailUrl(Url::fromPath('icingadb/downtime'));
|
||||
$content[] = (new ShowMore($downtimes, $link))->setBaseTarget('_next');
|
||||
} else {
|
||||
$content[] = new EmptyState(t('No downtimes scheduled.'));
|
||||
|
|
|
|||
|
|
@ -6,12 +6,14 @@ namespace Icinga\Module\Icingadb\Widget\Detail;
|
|||
|
||||
use Icinga\Exception\NotImplementedError;
|
||||
use Icinga\Module\Icingadb\Model\Comment;
|
||||
use Icinga\Module\Icingadb\Model\Downtime;
|
||||
use Icinga\Module\Icingadb\Model\Host;
|
||||
use Icinga\Module\Icingadb\Model\RedundancyGroup;
|
||||
use Icinga\Module\Icingadb\Model\Service;
|
||||
use Icinga\Module\Icingadb\Model\User;
|
||||
use Icinga\Module\Icingadb\Model\Usergroup;
|
||||
use Icinga\Module\Icingadb\View\CommentRenderer;
|
||||
use Icinga\Module\Icingadb\View\DowntimeRenderer;
|
||||
use Icinga\Module\Icingadb\View\HostRenderer;
|
||||
use Icinga\Module\Icingadb\View\RedundancyGroupRenderer;
|
||||
use Icinga\Module\Icingadb\View\ServiceRenderer;
|
||||
|
|
@ -59,6 +61,10 @@ class ObjectHeader extends BaseHtmlElement
|
|||
case $this->object instanceof Comment:
|
||||
$renderer = new CommentRenderer();
|
||||
|
||||
break;
|
||||
case $this->object instanceof Downtime:
|
||||
$renderer = new DowntimeRenderer();
|
||||
|
||||
break;
|
||||
default:
|
||||
throw new NotImplementedError('Not implemented');
|
||||
|
|
|
|||
|
|
@ -1,216 +0,0 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2020 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\Widget\ItemList;
|
||||
|
||||
use Icinga\Date\DateFormatter;
|
||||
use Icinga\Module\Icingadb\Common\HostLink;
|
||||
use Icinga\Module\Icingadb\Common\Icons;
|
||||
use Icinga\Module\Icingadb\Common\Links;
|
||||
use Icinga\Module\Icingadb\Common\NoSubjectLink;
|
||||
use Icinga\Module\Icingadb\Common\ObjectLinkDisabled;
|
||||
use Icinga\Module\Icingadb\Common\ServiceLink;
|
||||
use Icinga\Module\Icingadb\Common\TicketLinks;
|
||||
use Icinga\Module\Icingadb\Model\Downtime;
|
||||
use Icinga\Module\Icingadb\Widget\MarkdownLine;
|
||||
use ipl\Html\Attributes;
|
||||
use ipl\Html\BaseHtmlElement;
|
||||
use ipl\Html\Html;
|
||||
use ipl\Html\HtmlElement;
|
||||
use ipl\Html\TemplateString;
|
||||
use ipl\Html\Text;
|
||||
use ipl\Stdlib\Filter;
|
||||
use ipl\Web\Common\BaseListItem;
|
||||
use ipl\Web\Widget\Icon;
|
||||
use ipl\Web\Widget\Link;
|
||||
|
||||
/**
|
||||
* Downtime item of a downtime list. Represents one database row.
|
||||
*
|
||||
* @property Downtime $item
|
||||
* @property DowntimeList $list
|
||||
*/
|
||||
abstract class BaseDowntimeListItem extends BaseListItem
|
||||
{
|
||||
use HostLink;
|
||||
use ServiceLink;
|
||||
use NoSubjectLink;
|
||||
use ObjectLinkDisabled;
|
||||
use TicketLinks;
|
||||
|
||||
/** @var int Current Time */
|
||||
protected $currentTime;
|
||||
|
||||
/** @var int Duration */
|
||||
protected $duration;
|
||||
|
||||
/** @var int Downtime end time */
|
||||
protected $endTime;
|
||||
|
||||
/** @var bool Whether the downtime is active */
|
||||
protected $isActive;
|
||||
|
||||
/** @var int Downtime start time */
|
||||
protected $startTime;
|
||||
|
||||
protected function init(): void
|
||||
{
|
||||
if (
|
||||
isset($this->item->start_time, $this->item->end_time)
|
||||
&& $this->item->is_flexible
|
||||
&& $this->item->is_in_effect
|
||||
) {
|
||||
$this->startTime = $this->item->start_time->getTimestamp();
|
||||
$this->endTime = $this->item->end_time->getTimestamp();
|
||||
} else {
|
||||
$this->startTime = $this->item->scheduled_start_time->getTimestamp();
|
||||
$this->endTime = $this->item->scheduled_end_time->getTimestamp();
|
||||
}
|
||||
|
||||
$this->currentTime = time();
|
||||
|
||||
$this->isActive = $this->item->is_in_effect
|
||||
|| $this->item->is_flexible && $this->item->scheduled_start_time->getTimestamp() <= $this->currentTime;
|
||||
|
||||
$until = ($this->isActive ? $this->endTime : $this->startTime) - $this->currentTime;
|
||||
$this->duration = explode(' ', DateFormatter::formatDuration(
|
||||
$until <= 3600 ? $until : $until + (3600 - ((int) $until % 3600))
|
||||
), 2)[0];
|
||||
|
||||
$this->list->addDetailFilterAttribute($this, Filter::equal('name', $this->item->name));
|
||||
$this->list->addMultiselectFilterAttribute($this, Filter::equal('name', $this->item->name));
|
||||
$this->setObjectLinkDisabled($this->list->getObjectLinkDisabled());
|
||||
$this->setNoSubjectLink($this->list->getNoSubjectLink());
|
||||
$this->setTicketLinkEnabled($this->list->getTicketLinkEnabled());
|
||||
|
||||
if ($this->item->is_in_effect) {
|
||||
$this->getAttributes()->add('class', 'in-effect');
|
||||
}
|
||||
}
|
||||
|
||||
protected function createProgress(): BaseHtmlElement
|
||||
{
|
||||
return new HtmlElement(
|
||||
'div',
|
||||
Attributes::create([
|
||||
'class' => 'progress',
|
||||
'data-animate-progress' => true,
|
||||
'data-start-time' => $this->startTime,
|
||||
'data-end-time' => $this->endTime
|
||||
]),
|
||||
new HtmlElement(
|
||||
'div',
|
||||
Attributes::create(['class' => 'bar'])
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
protected function assembleCaption(BaseHtmlElement $caption): void
|
||||
{
|
||||
$markdownLine = new MarkdownLine($this->createTicketLinks($this->item->comment));
|
||||
$caption->getAttributes()->add($markdownLine->getAttributes());
|
||||
$caption->addHtml(
|
||||
new HtmlElement(
|
||||
'span',
|
||||
null,
|
||||
new Icon(Icons::USER),
|
||||
Text::create($this->item->author)
|
||||
),
|
||||
Text::create(': ')
|
||||
)->addFrom($markdownLine);
|
||||
}
|
||||
|
||||
protected function assembleTitle(BaseHtmlElement $title): void
|
||||
{
|
||||
if ($this->getObjectLinkDisabled()) {
|
||||
$link = null;
|
||||
} elseif ($this->item->object_type === 'host') {
|
||||
$link = $this->createHostLink($this->item->host, true);
|
||||
} else {
|
||||
$link = $this->createServiceLink($this->item->service, $this->item->service->host, true);
|
||||
}
|
||||
|
||||
if ($this->item->is_flexible) {
|
||||
if ($link !== null) {
|
||||
$template = t('{{#link}}Flexible Downtime{{/link}} for %s');
|
||||
} else {
|
||||
$template = t('Flexible Downtime');
|
||||
}
|
||||
} else {
|
||||
if ($link !== null) {
|
||||
$template = t('{{#link}}Fixed Downtime{{/link}} for %s');
|
||||
} else {
|
||||
$template = t('Fixed Downtime');
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->getNoSubjectLink()) {
|
||||
if ($link === null) {
|
||||
$title->addHtml(HtmlElement::create('span', [ 'class' => 'subject'], $template));
|
||||
} else {
|
||||
$title->addHtml(TemplateString::create(
|
||||
$template,
|
||||
['link' => HtmlElement::create('span', [ 'class' => 'subject'])],
|
||||
$link
|
||||
));
|
||||
}
|
||||
} else {
|
||||
if ($link === null) {
|
||||
$title->addHtml(new Link($template, Links::downtime($this->item)));
|
||||
} else {
|
||||
$title->addHtml(TemplateString::create(
|
||||
$template,
|
||||
['link' => new Link('', Links::downtime($this->item))],
|
||||
$link
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function assembleVisual(BaseHtmlElement $visual): void
|
||||
{
|
||||
$dateTime = DateFormatter::formatDateTime($this->endTime);
|
||||
|
||||
if ($this->isActive) {
|
||||
$visual->addHtml(Html::sprintf(
|
||||
t('%s left', '<timespan>..'),
|
||||
Html::tag(
|
||||
'strong',
|
||||
Html::tag(
|
||||
'time',
|
||||
[
|
||||
'datetime' => $dateTime,
|
||||
'title' => $dateTime
|
||||
],
|
||||
$this->duration
|
||||
)
|
||||
)
|
||||
));
|
||||
} else {
|
||||
$visual->addHtml(Html::sprintf(
|
||||
t('in %s', '..<timespan>'),
|
||||
Html::tag('strong', $this->duration)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
protected function createTimestamp(): ?BaseHtmlElement
|
||||
{
|
||||
$dateTime = DateFormatter::formatDateTime($this->isActive ? $this->endTime : $this->startTime);
|
||||
|
||||
return Html::tag(
|
||||
'time',
|
||||
[
|
||||
'datetime' => $dateTime,
|
||||
'title' => $dateTime
|
||||
],
|
||||
sprintf(
|
||||
$this->isActive
|
||||
? t('expires in %s', '..<timespan>')
|
||||
: t('starts in %s', '..<timespan>'),
|
||||
$this->duration
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2020 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\Widget\ItemList;
|
||||
|
||||
use Icinga\Module\Icingadb\Common\CaptionDisabled;
|
||||
use Icinga\Module\Icingadb\Common\DetailActions;
|
||||
use Icinga\Module\Icingadb\Common\Links;
|
||||
use Icinga\Module\Icingadb\Common\NoSubjectLink;
|
||||
use Icinga\Module\Icingadb\Common\ObjectLinkDisabled;
|
||||
use Icinga\Module\Icingadb\Common\TicketLinks;
|
||||
use Icinga\Module\Icingadb\Common\ViewMode;
|
||||
use ipl\Web\Common\BaseItemList;
|
||||
use ipl\Web\Url;
|
||||
|
||||
class DowntimeList extends BaseItemList
|
||||
{
|
||||
use CaptionDisabled;
|
||||
use NoSubjectLink;
|
||||
use ObjectLinkDisabled;
|
||||
use ViewMode;
|
||||
use TicketLinks;
|
||||
use DetailActions;
|
||||
|
||||
protected $defaultAttributes = ['class' => 'downtime-list'];
|
||||
|
||||
protected function getItemClass(): string
|
||||
{
|
||||
$viewMode = $this->getViewMode();
|
||||
|
||||
$this->addAttributes(['class' => $viewMode]);
|
||||
|
||||
if ($viewMode === 'minimal') {
|
||||
return DowntimeListItemMinimal::class;
|
||||
} elseif ($viewMode === 'detailed') {
|
||||
$this->removeAttribute('class', 'default-layout');
|
||||
}
|
||||
|
||||
return DowntimeListItem::class;
|
||||
}
|
||||
|
||||
protected function init(): void
|
||||
{
|
||||
$this->initializeDetailActions();
|
||||
$this->setMultiselectUrl(Links::downtimesDetails());
|
||||
$this->setDetailUrl(Url::fromPath('icingadb/downtime'));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2020 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\Widget\ItemList;
|
||||
|
||||
use Icinga\Module\Icingadb\Common\ListItemCommonLayout;
|
||||
use ipl\Html\BaseHtmlElement;
|
||||
|
||||
class DowntimeListItem extends BaseDowntimeListItem
|
||||
{
|
||||
use ListItemCommonLayout;
|
||||
|
||||
protected function assembleMain(BaseHtmlElement $main): void
|
||||
{
|
||||
if ($this->item->is_in_effect) {
|
||||
$main->add($this->createProgress());
|
||||
}
|
||||
|
||||
$main->add($this->createHeader());
|
||||
$main->add($this->createCaption());
|
||||
}
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2020 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\Widget\ItemList;
|
||||
|
||||
use Icinga\Module\Icingadb\Common\ListItemMinimalLayout;
|
||||
|
||||
class DowntimeListItemMinimal extends BaseDowntimeListItem
|
||||
{
|
||||
use ListItemMinimalLayout;
|
||||
|
||||
protected function init(): void
|
||||
{
|
||||
parent::init();
|
||||
|
||||
if ($this->list->isCaptionDisabled()) {
|
||||
$this->setCaptionDisabled();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -8,6 +8,7 @@ use Icinga\Exception\NotImplementedError;
|
|||
use Icinga\Module\Icingadb\Common\DetailActions;
|
||||
use Icinga\Module\Icingadb\Model\Comment;
|
||||
use Icinga\Module\Icingadb\Model\DependencyNode;
|
||||
use Icinga\Module\Icingadb\Model\Downtime;
|
||||
use Icinga\Module\Icingadb\Model\Host;
|
||||
use Icinga\Module\Icingadb\Model\RedundancyGroup;
|
||||
use Icinga\Module\Icingadb\Model\Service;
|
||||
|
|
@ -16,6 +17,7 @@ use Icinga\Module\Icingadb\Model\User;
|
|||
use Icinga\Module\Icingadb\Model\Usergroup;
|
||||
use Icinga\Module\Icingadb\Redis\VolatileStateResults;
|
||||
use Icinga\Module\Icingadb\View\CommentRenderer;
|
||||
use Icinga\Module\Icingadb\View\DowntimeRenderer;
|
||||
use Icinga\Module\Icingadb\View\HostRenderer;
|
||||
use Icinga\Module\Icingadb\View\RedundancyGroupRenderer;
|
||||
use Icinga\Module\Icingadb\View\ServiceRenderer;
|
||||
|
|
@ -61,6 +63,8 @@ class ObjectList extends ItemList
|
|||
return new UserRenderer();
|
||||
} elseif ($item instanceof Comment) {
|
||||
return new CommentRenderer();
|
||||
} elseif ($item instanceof Downtime) {
|
||||
return new DowntimeRenderer();
|
||||
}
|
||||
|
||||
throw new NotImplementedError('Not implemented');
|
||||
|
|
@ -132,6 +136,10 @@ class ObjectList extends ItemList
|
|||
$layout->after(ItemLayout::VISUAL, 'icon-image');
|
||||
}
|
||||
|
||||
if ($item instanceof Downtime) {
|
||||
$layout->before(ItemLayout::HEADER, 'progress');
|
||||
}
|
||||
|
||||
return $layout;
|
||||
}
|
||||
|
||||
|
|
@ -195,7 +203,7 @@ class ObjectList extends ItemList
|
|||
$this->addDetailFilterAttribute($item, Filter::equal('name', $object->name));
|
||||
|
||||
break;
|
||||
case $object instanceof Comment:
|
||||
case $object instanceof Comment || $object instanceof Downtime:
|
||||
$this->addDetailFilterAttribute($item, Filter::equal('name', $object->name));
|
||||
$this->addMultiSelectFilterAttribute($item, Filter::equal('name', $object->name));
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,9 @@ namespace Icinga\Module\Icingadb\Widget\ItemList;
|
|||
|
||||
use Icinga\Exception\NotImplementedError;
|
||||
use Icinga\Module\Icingadb\Model\Comment;
|
||||
use Icinga\Module\Icingadb\Model\Downtime;
|
||||
use Icinga\Module\Icingadb\View\CommentRenderer;
|
||||
use Icinga\Module\Icingadb\View\DowntimeRenderer;
|
||||
use ipl\Orm\Model;
|
||||
use ipl\Web\Widget\ItemList;
|
||||
|
||||
|
|
@ -24,6 +26,8 @@ class TicketLinkObjectList extends ObjectList
|
|||
ItemList::__construct($data, function (Model $item) {
|
||||
if ($item instanceof Comment) {
|
||||
return (new CommentRenderer())->setIsDetailView();
|
||||
} elseif ($item instanceof Downtime) {
|
||||
return (new DowntimeRenderer())->setIsDetailView();
|
||||
}
|
||||
|
||||
throw new NotImplementedError('Not implemented');
|
||||
|
|
|
|||
|
|
@ -1,17 +1,22 @@
|
|||
// Style
|
||||
.item-layout.downtime {
|
||||
.visual {
|
||||
background-color: @gray-lighter;
|
||||
}
|
||||
|
||||
.downtime-list .list-item,
|
||||
.downtime-detail .list-item {
|
||||
&.in-effect .visual {
|
||||
background-color: @color-ok;
|
||||
color: @text-color-on-icinga-blue;
|
||||
}
|
||||
}
|
||||
|
||||
.list-item.downtime {
|
||||
.progress {
|
||||
> .bar {
|
||||
background-color: @color-ok;
|
||||
}
|
||||
}
|
||||
|
||||
.visual {
|
||||
background-color: @gray-lighter;
|
||||
}
|
||||
|
||||
.main {
|
||||
border-top: 1px solid @gray-light;
|
||||
}
|
||||
|
|
@ -23,44 +28,14 @@
|
|||
border-top: 1px solid @gray-light;
|
||||
}
|
||||
}
|
||||
|
||||
&.in-effect {
|
||||
.visual {
|
||||
background-color: @color-ok;
|
||||
color: @text-color-on-icinga-blue;
|
||||
}
|
||||
|
||||
.main {
|
||||
padding-top: 0; // If active the progress bar represents the padding top
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Layout
|
||||
|
||||
.downtime-list .list-item {
|
||||
.item-layout.downtime {
|
||||
.caption > * {
|
||||
display: inline;
|
||||
}
|
||||
}
|
||||
|
||||
.downtime-list .list-item,
|
||||
.downtime-detail .list-item {
|
||||
.progress {
|
||||
height: 2px;
|
||||
margin-bottom: ~"calc(.5em - 2px)";
|
||||
min-width: 100%;
|
||||
position: relative;
|
||||
|
||||
> .bar {
|
||||
height: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
&:first-child .main .progress > .bar {
|
||||
height: ~"calc(100% + 1px)"; // +1px due to the border added exclusively for the first item
|
||||
}
|
||||
|
||||
.visual {
|
||||
justify-content: center;
|
||||
|
|
@ -77,7 +52,29 @@
|
|||
}
|
||||
}
|
||||
|
||||
.item-list.downtime-list.minimal .list-item {
|
||||
.list-item.downtime {
|
||||
.progress {
|
||||
height: 2px;
|
||||
margin-bottom: ~"calc(.5em - 2px)";
|
||||
min-width: 100%;
|
||||
position: relative;
|
||||
|
||||
> .bar {
|
||||
height: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
&:first-child .main .progress > .bar {
|
||||
height: ~"calc(100% + 1px)"; // +1px due to the border added exclusively for the first item
|
||||
}
|
||||
|
||||
.main:has(.progress) {
|
||||
padding-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.minimal-item-layout.downtime {
|
||||
.visual {
|
||||
display: block;
|
||||
line-height: 1.5;
|
||||
Loading…
Reference in a new issue