summaryrefslogtreecommitdiffstats
path: root/library/Icingadb/Widget/ItemList/StateListItem.php
blob: d0b336341d6f9aa640dba6e988e4d445bfbc3d41 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
<?php

/* Icinga DB Web | (c) 2020 Icinga GmbH | GPLv2 */

namespace Icinga\Module\Icingadb\Widget\ItemList;

use Icinga\Module\Icingadb\Common\Icons;
use Icinga\Module\Icingadb\Model\State;
use Icinga\Module\Icingadb\Util\PluginOutput;
use Icinga\Module\Icingadb\Widget\CheckAttempt;
use Icinga\Module\Icingadb\Widget\IconImage;
use Icinga\Module\Icingadb\Widget\PluginOutputContainer;
use ipl\Html\HtmlElement;
use ipl\Web\Common\BaseListItem;
use ipl\Web\Widget\EmptyState;
use ipl\Web\Widget\TimeSince;
use ipl\Html\BaseHtmlElement;
use ipl\Html\Html;
use ipl\Html\Text;
use ipl\Web\Widget\Icon;
use ipl\Web\Widget\StateBall;

/**
 * Host or service item of a host or service list. Represents one database row.
 */
abstract class StateListItem extends BaseListItem
{
    /** @var StateList The list where the item is part of */
    protected $list;

    /** @var State The state of the item */
    protected $state;

    protected function init(): void
    {
        $this->state = $this->item->state;

        if (isset($this->item->icon_image->icon_image)) {
            $this->list->setHasIconImages(true);
        }
    }

    abstract protected function createSubject();

    abstract protected function getStateBallSize(): string;

    /**
     * @return ?BaseHtmlElement
     */
    protected function createIconImage(): ?BaseHtmlElement
    {
        if (! $this->list->hasIconImages()) {
            return null;
        }

        $iconImage = HtmlElement::create('div', [
            'class' => 'icon-image',
        ]);

        $this->assembleIconImage($iconImage);

        return $iconImage;
    }

    protected function assembleCaption(BaseHtmlElement $caption): void
    {
        if ($this->state->soft_state === null && $this->state->output === null) {
            $caption->addHtml(Text::create(t('Waiting for Icinga DB to synchronize the state.')));
        } else {
            if (empty($this->state->output)) {
                $pluginOutput = new EmptyState(t('Output unavailable.'));
            } else {
                $pluginOutput = new PluginOutputContainer(PluginOutput::fromObject($this->item));
            }

            $caption->addHtml($pluginOutput);
        }
    }

    protected function assembleIconImage(BaseHtmlElement $iconImage): void
    {
        if (isset($this->item->icon_image->icon_image)) {
            $iconImage->addHtml(new IconImage($this->item->icon_image->icon_image, $this->item->icon_image_alt));
        } else {
            $iconImage->addAttributes(['class' => 'placeholder']);
        }
    }

    protected function assembleTitle(BaseHtmlElement $title): void
    {
        $title->addHtml(Html::sprintf(
            t('%s is %s', '<hostname> is <state-text>'),
            $this->createSubject(),
            Html::tag('span', ['class' => 'state-text'], $this->state->getStateTextTranslated())
        ));
    }

    protected function assembleVisual(BaseHtmlElement $visual): void
    {
        $stateBall = new StateBall($this->state->getStateText(), $this->getStateBallSize());
        $stateBall->add($this->state->getIcon());
        if ($this->state->is_handled || ! $this->state->is_reachable) {
            $stateBall->getAttributes()->add('class', 'handled');
        }

        $visual->addHtml($stateBall);
        if ($this->state->state_type === 'soft') {
            $visual->addHtml(
                new CheckAttempt((int) $this->state->check_attempt, (int) $this->item->max_check_attempts)
            );
        }
    }

    protected function createTimestamp(): ?BaseHtmlElement
    {
        $since = null;
        if ($this->state->is_overdue) {
            $since = new TimeSince($this->state->next_update->getTimestamp());
            $since->prepend(t('Overdue') . ' ');
            $since->prependHtml(new Icon(Icons::WARNING));
        } elseif ($this->state->last_state_change !== null && $this->state->last_state_change->getTimestamp() > 0) {
            $since = new TimeSince($this->state->last_state_change->getTimestamp());
        }

        return $since;
    }

    protected function assemble(): void
    {
        if ($this->state->is_overdue) {
            $this->addAttributes(['class' => 'overdue']);
        }

        $this->add([
            $this->createVisual(),
            $this->createIconImage(),
            $this->createMain()
        ]);
    }
}