mirror of
https://github.com/Icinga/icingadb-web.git
synced 2026-05-28 04:36:06 -04:00
Introduce TicketLinkObjectList and CommentRenderer
TicketLinkObjectList: This class creates object list with ticket links using TicketLinks trait CommentRenderer: Defines the rendering rules for Comment object Cleanup css and unused classes Adjust comment-popup.less
This commit is contained in:
parent
bfe1681859
commit
c55f1dceb8
16 changed files with 254 additions and 307 deletions
|
|
@ -10,7 +10,7 @@ use Icinga\Module\Icingadb\Common\Links;
|
|||
use Icinga\Module\Icingadb\Model\Comment;
|
||||
use Icinga\Module\Icingadb\Web\Controller;
|
||||
use Icinga\Module\Icingadb\Widget\Detail\CommentDetail;
|
||||
use Icinga\Module\Icingadb\Widget\ItemList\CommentList;
|
||||
use Icinga\Module\Icingadb\Widget\Detail\ObjectHeader;
|
||||
use ipl\Stdlib\Filter;
|
||||
use ipl\Web\Url;
|
||||
|
||||
|
|
@ -49,13 +49,9 @@ class CommentController extends Controller
|
|||
|
||||
public function indexAction()
|
||||
{
|
||||
$this->addControl((new CommentList([$this->comment]))
|
||||
->setViewMode('minimal')
|
||||
->setDetailActionsDisabled()
|
||||
->setCaptionDisabled()
|
||||
->setNoSubjectLink());
|
||||
$this->addControl(new ObjectHeader($this->comment));
|
||||
|
||||
$this->addContent((new CommentDetail($this->comment))->setTicketLinkEnabled());
|
||||
$this->addContent(new CommentDetail($this->comment));
|
||||
|
||||
$this->setAutorefreshInterval(10);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@ use Icinga\Module\Icingadb\Forms\Command\Object\DeleteCommentForm;
|
|||
use Icinga\Module\Icingadb\Model\Comment;
|
||||
use Icinga\Module\Icingadb\Web\Control\SearchBar\ObjectSuggestions;
|
||||
use Icinga\Module\Icingadb\Web\Controller;
|
||||
use Icinga\Module\Icingadb\Widget\ItemList\CommentList;
|
||||
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;
|
||||
|
|
@ -81,7 +81,12 @@ class CommentsController extends Controller
|
|||
|
||||
$results = $comments->execute();
|
||||
|
||||
$this->addContent((new CommentList($results))->setViewMode($viewModeSwitcher->getViewMode()));
|
||||
$this->addContent(
|
||||
(new ObjectList($results))
|
||||
->setViewMode($viewModeSwitcher->getViewMode())
|
||||
->setMultiselectUrl(Links::commentsDetails())
|
||||
->setDetailUrl(Url::fromPath('icingadb/comment'))
|
||||
);
|
||||
|
||||
if ($compact) {
|
||||
$this->addContent(
|
||||
|
|
@ -156,7 +161,7 @@ class CommentsController extends Controller
|
|||
|
||||
$rs = $comments->execute();
|
||||
|
||||
$this->addControl((new CommentList($rs))->setViewMode('minimal'));
|
||||
$this->addControl((new ObjectList($rs))->setViewMode('minimal'));
|
||||
|
||||
$this->addControl(new ShowMore(
|
||||
$rs,
|
||||
|
|
|
|||
|
|
@ -5,11 +5,12 @@
|
|||
namespace Icinga\Module\Icingadb\Common;
|
||||
|
||||
use Icinga\Application\Hook;
|
||||
use Icinga\Application\Hook\TicketHook;
|
||||
|
||||
trait TicketLinks
|
||||
{
|
||||
/** @var bool */
|
||||
protected $ticketLinkEnabled = false;
|
||||
protected $ticketLinkEnabled = false; // TODO: Remove once all usages are removed
|
||||
|
||||
/**
|
||||
* Set whether list items should render host and service links
|
||||
|
|
@ -43,11 +44,9 @@ trait TicketLinks
|
|||
public function createTicketLinks($text): string
|
||||
{
|
||||
if (Hook::has('ticket')) {
|
||||
/** @var TicketHook $tickets */
|
||||
$tickets = Hook::first('ticket');
|
||||
}
|
||||
|
||||
if ($this->getTicketLinkEnabled() && isset($tickets)) {
|
||||
/** @var \Icinga\Application\Hook\TicketHook $tickets */
|
||||
return $tickets->createLinks($text);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ use Icinga\Module\Icingadb\Util\PerfDataSet;
|
|||
use Icinga\Module\Icingadb\Util\PluginOutput;
|
||||
use Icinga\Module\Icingadb\Widget\CheckAttempt;
|
||||
use Icinga\Module\Icingadb\Widget\IconImage;
|
||||
use Icinga\Module\Icingadb\Widget\ItemList\CommentList;
|
||||
use Icinga\Module\Icingadb\Widget\PluginOutputContainer;
|
||||
use Icinga\Module\Icingadb\Widget\StateChange;
|
||||
use ipl\Html\Attributes;
|
||||
|
|
@ -25,6 +24,7 @@ use ipl\Html\Text;
|
|||
use ipl\Html\ValidHtml;
|
||||
use ipl\I18n\Translation;
|
||||
use ipl\Web\Common\ItemRenderer;
|
||||
use ipl\Web\Layout\ItemLayout;
|
||||
use ipl\Web\Widget\EmptyState;
|
||||
use ipl\Web\Widget\Icon;
|
||||
use ipl\Web\Widget\StateBall;
|
||||
|
|
@ -187,16 +187,15 @@ abstract class BaseHostAndServiceRenderer implements ItemRenderer
|
|||
$comment->host = $item;
|
||||
}
|
||||
|
||||
$comment = (new CommentList([$comment]))
|
||||
->setNoSubjectLink()
|
||||
->setObjectLinkDisabled()
|
||||
->setDetailActionsDisabled();
|
||||
|
||||
$statusIcons->addHtml(
|
||||
new HtmlElement(
|
||||
'div',
|
||||
Attributes::create(['class' => 'comment-wrapper']),
|
||||
new HtmlElement('div', Attributes::create(['class' => 'comment-popup']), $comment),
|
||||
new HtmlElement(
|
||||
'div',
|
||||
Attributes::create(['class' => 'comment-popup']),
|
||||
new ItemLayout($comment, (new CommentRenderer())->setIsDetailView())
|
||||
),
|
||||
(new Icon('comments', ['class' => 'comment-icon']))
|
||||
)
|
||||
);
|
||||
|
|
|
|||
161
library/Icingadb/View/CommentRenderer.php
Normal file
161
library/Icingadb/View/CommentRenderer.php
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2025 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\View;
|
||||
|
||||
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\Comment;
|
||||
use Icinga\Module\Icingadb\Widget\MarkdownLine;
|
||||
use ipl\Html\Attributes;
|
||||
use ipl\Html\FormattedString;
|
||||
use ipl\Html\HtmlDocument;
|
||||
use ipl\Html\HtmlElement;
|
||||
use ipl\Html\Text;
|
||||
use ipl\I18n\Translation;
|
||||
use ipl\Web\Common\ItemRenderer;
|
||||
use ipl\Web\Widget\Icon;
|
||||
use ipl\Web\Widget\Link;
|
||||
use ipl\Web\Widget\TimeAgo;
|
||||
use ipl\Web\Widget\TimeUntil;
|
||||
|
||||
/** @implements ItemRenderer<Comment> */
|
||||
class CommentRenderer implements ItemRenderer
|
||||
{
|
||||
use Translation;
|
||||
use TicketLinks;
|
||||
use HostLink;
|
||||
use ServiceLink;
|
||||
|
||||
/**
|
||||
* @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;
|
||||
}
|
||||
|
||||
public function assembleAttributes($item, Attributes $attributes, string $layout): void
|
||||
{
|
||||
$attributes->get('class')->addValue('comment');
|
||||
}
|
||||
|
||||
public function assembleVisual($item, HtmlDocument $visual, string $layout): void
|
||||
{
|
||||
$visual->addHtml(new HtmlElement(
|
||||
'div',
|
||||
Attributes::create(['class' => 'user-ball']),
|
||||
Text::create($item->author[0])
|
||||
));
|
||||
}
|
||||
|
||||
public function assembleTitle($item, HtmlDocument $title, string $layout): void
|
||||
{
|
||||
$isAck = $item->entry_type === 'ack';
|
||||
$expires = $item->expire_time;
|
||||
|
||||
$subjectText = sprintf(
|
||||
$isAck
|
||||
? $this->translate('%s acknowledged', '<username>..')
|
||||
: $this->translate('%s commented', '<username>..'),
|
||||
$item->author
|
||||
);
|
||||
|
||||
$headerParts = [
|
||||
new Icon(Icons::USER),
|
||||
$layout === 'header'
|
||||
? new HtmlElement('span', Attributes::create(['class' => 'subject']), Text::create($subjectText))
|
||||
: new Link($subjectText, Links::comment($item), ['class' => 'subject'])
|
||||
];
|
||||
|
||||
if ($isAck) {
|
||||
$label = [Text::create('ack')];
|
||||
|
||||
if ($item->is_persistent) {
|
||||
array_unshift($label, new Icon(Icons::IS_PERSISTENT));
|
||||
}
|
||||
|
||||
$headerParts[] = Text::create(' ');
|
||||
$headerParts[] = new HtmlElement('span', Attributes::create(['class' => 'ack-badge badge']), ...$label);
|
||||
}
|
||||
|
||||
if ($expires !== null) {
|
||||
$headerParts[] = Text::create(' ');
|
||||
$headerParts[] = new HtmlElement(
|
||||
'span',
|
||||
Attributes::create(['class' => 'ack-badge badge']),
|
||||
Text::create($this->translate('EXPIRES'))
|
||||
);
|
||||
}
|
||||
|
||||
if ($this->isDetailView) {
|
||||
// pass
|
||||
} elseif ($item->object_type === 'host') {
|
||||
$headerParts[] = $this->createHostLink($item->host, true);
|
||||
} else {
|
||||
$headerParts[] = $this->createServiceLink($item->service, $item->service->host, true);
|
||||
}
|
||||
|
||||
$title->addHtml(...$headerParts);
|
||||
}
|
||||
|
||||
public function assembleCaption($item, HtmlDocument $caption, string $layout): void
|
||||
{
|
||||
$markdownLine = new MarkdownLine($this->isDetailView ? $this->createTicketLinks($item->text) : $item->text);
|
||||
|
||||
$caption->getAttributes()->add($markdownLine->getAttributes());
|
||||
$caption->addFrom($markdownLine);
|
||||
}
|
||||
|
||||
public function assembleExtendedInfo($item, HtmlDocument $info, string $layout): void
|
||||
{
|
||||
if ($item->expire_time) {
|
||||
$info->addHtml(new HtmlElement(
|
||||
'span',
|
||||
null,
|
||||
FormattedString::create(
|
||||
$this->translate("expires %s"),
|
||||
new TimeUntil($item->expire_time->getTimestamp())
|
||||
)
|
||||
));
|
||||
} else {
|
||||
$info->addHtml(new HtmlElement(
|
||||
'span',
|
||||
null,
|
||||
FormattedString::create(
|
||||
$this->translate("created %s"),
|
||||
new TimeAgo($item->entry_time->getTimestamp())
|
||||
)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
public function assembleFooter($item, HtmlDocument $footer, string $layout): void
|
||||
{
|
||||
}
|
||||
|
||||
public function assemble($item, string $name, HtmlDocument $element, string $layout): bool
|
||||
{
|
||||
return false; // no custom sections
|
||||
}
|
||||
}
|
||||
|
|
@ -29,6 +29,7 @@ use Icinga\Module\Icingadb\Model\UnreachableParent;
|
|||
use Icinga\Module\Icingadb\Redis\VolatileStateResults;
|
||||
use Icinga\Module\Icingadb\Web\Navigation\Action;
|
||||
use Icinga\Module\Icingadb\Widget\ItemList\ObjectList;
|
||||
use Icinga\Module\Icingadb\Widget\ItemList\TicketLinkObjectList;
|
||||
use Icinga\Module\Icingadb\Widget\MarkdownText;
|
||||
use Icinga\Module\Icingadb\Common\ServiceLinks;
|
||||
use Icinga\Module\Icingadb\Forms\Command\Object\ToggleObjectFeaturesForm;
|
||||
|
|
@ -42,11 +43,11 @@ use Icinga\Module\Icingadb\Widget\ItemList\DowntimeList;
|
|||
use Icinga\Module\Icingadb\Widget\ShowMore;
|
||||
use ipl\Sql\Expression;
|
||||
use ipl\Sql\Filter\Exists;
|
||||
use ipl\Web\Url;
|
||||
use ipl\Web\Widget\CopyToClipboard;
|
||||
use ipl\Web\Widget\EmptyState;
|
||||
use ipl\Web\Widget\EmptyStateBar;
|
||||
use ipl\Web\Widget\HorizontalKeyValue;
|
||||
use Icinga\Module\Icingadb\Widget\ItemList\CommentList;
|
||||
use Icinga\Module\Icingadb\Widget\PluginOutputContainer;
|
||||
use Icinga\Module\Icingadb\Widget\TagList;
|
||||
use Icinga\Module\Monitoring\Hook\DetailviewExtensionHook;
|
||||
|
|
@ -231,7 +232,9 @@ class ObjectDetail extends BaseHtmlElement
|
|||
$content = [Html::tag('h2', t('Comments'))];
|
||||
|
||||
if ($comments->hasResult()) {
|
||||
$content[] = (new CommentList($comments))->setObjectLinkDisabled()->setTicketLinkEnabled();
|
||||
$content[] = (new TicketLinkObjectList($comments))
|
||||
->setMultiselectUrl(Links::commentsDetails())
|
||||
->setDetailUrl(Url::fromPath('icingadb/comment'));
|
||||
$content[] = (new ShowMore($comments, $link))->setBaseTarget('_next');
|
||||
} else {
|
||||
$content[] = new EmptyState(t('No comments created.'));
|
||||
|
|
|
|||
|
|
@ -5,11 +5,13 @@
|
|||
namespace Icinga\Module\Icingadb\Widget\Detail;
|
||||
|
||||
use Icinga\Exception\NotImplementedError;
|
||||
use Icinga\Module\Icingadb\Model\Comment;
|
||||
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\HostRenderer;
|
||||
use Icinga\Module\Icingadb\View\RedundancyGroupRenderer;
|
||||
use Icinga\Module\Icingadb\View\ServiceRenderer;
|
||||
|
|
@ -53,6 +55,10 @@ class ObjectHeader extends BaseHtmlElement
|
|||
case $this->object instanceof User:
|
||||
$renderer = new UserRenderer();
|
||||
|
||||
break;
|
||||
case $this->object instanceof Comment:
|
||||
$renderer = new CommentRenderer();
|
||||
|
||||
break;
|
||||
default:
|
||||
throw new NotImplementedError('Not implemented');
|
||||
|
|
|
|||
|
|
@ -1,131 +0,0 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2020 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\Widget\ItemList;
|
||||
|
||||
use Icinga\Module\Icingadb\Common\NoSubjectLink;
|
||||
use Icinga\Module\Icingadb\Common\ObjectLinkDisabled;
|
||||
use Icinga\Module\Icingadb\Common\TicketLinks;
|
||||
use ipl\Html\Html;
|
||||
use Icinga\Module\Icingadb\Common\HostLink;
|
||||
use Icinga\Module\Icingadb\Common\Icons;
|
||||
use Icinga\Module\Icingadb\Common\Links;
|
||||
use Icinga\Module\Icingadb\Widget\MarkdownLine;
|
||||
use Icinga\Module\Icingadb\Common\ServiceLink;
|
||||
use Icinga\Module\Icingadb\Model\Comment;
|
||||
use ipl\Html\FormattedString;
|
||||
use ipl\Web\Common\BaseListItem;
|
||||
use ipl\Web\Widget\TimeAgo;
|
||||
use ipl\Html\Attributes;
|
||||
use ipl\Html\BaseHtmlElement;
|
||||
use ipl\Html\HtmlElement;
|
||||
use ipl\Html\Text;
|
||||
use ipl\Stdlib\Filter;
|
||||
use ipl\Web\Widget\Icon;
|
||||
use ipl\Web\Widget\Link;
|
||||
use ipl\Web\Widget\TimeUntil;
|
||||
|
||||
/**
|
||||
* Comment item of a comment list. Represents one database row.
|
||||
*
|
||||
* @property Comment $item
|
||||
* @property CommentList $list
|
||||
*/
|
||||
abstract class BaseCommentListItem extends BaseListItem
|
||||
{
|
||||
use HostLink;
|
||||
use ServiceLink;
|
||||
use NoSubjectLink;
|
||||
use ObjectLinkDisabled;
|
||||
use TicketLinks;
|
||||
|
||||
protected function assembleCaption(BaseHtmlElement $caption): void
|
||||
{
|
||||
$markdownLine = new MarkdownLine($this->createTicketLinks($this->item->text));
|
||||
|
||||
$caption->getAttributes()->add($markdownLine->getAttributes());
|
||||
$caption->addFrom($markdownLine);
|
||||
}
|
||||
|
||||
protected function assembleTitle(BaseHtmlElement $title): void
|
||||
{
|
||||
$isAck = $this->item->entry_type === 'ack';
|
||||
$expires = $this->item->expire_time;
|
||||
|
||||
$subjectText = sprintf(
|
||||
$isAck ? t('%s acknowledged', '<username>..') : t('%s commented', '<username>..'),
|
||||
$this->item->author
|
||||
);
|
||||
|
||||
$headerParts = [
|
||||
new Icon(Icons::USER),
|
||||
$this->getNoSubjectLink()
|
||||
? new HtmlElement('span', Attributes::create(['class' => 'subject']), Text::create($subjectText))
|
||||
: new Link($subjectText, Links::comment($this->item), ['class' => 'subject'])
|
||||
];
|
||||
|
||||
if ($isAck) {
|
||||
$label = [Text::create('ack')];
|
||||
|
||||
if ($this->item->is_persistent) {
|
||||
array_unshift($label, new Icon(Icons::IS_PERSISTENT));
|
||||
}
|
||||
|
||||
$headerParts[] = Text::create(' ');
|
||||
$headerParts[] = new HtmlElement('span', Attributes::create(['class' => 'ack-badge badge']), ...$label);
|
||||
}
|
||||
|
||||
if ($expires !== null) {
|
||||
$headerParts[] = Text::create(' ');
|
||||
$headerParts[] = new HtmlElement(
|
||||
'span',
|
||||
Attributes::create(['class' => 'ack-badge badge']),
|
||||
Text::create(t('EXPIRES'))
|
||||
);
|
||||
}
|
||||
|
||||
if ($this->getObjectLinkDisabled()) {
|
||||
// pass
|
||||
} elseif ($this->item->object_type === 'host') {
|
||||
$headerParts[] = $this->createHostLink($this->item->host, true);
|
||||
} else {
|
||||
$headerParts[] = $this->createServiceLink($this->item->service, $this->item->service->host, true);
|
||||
}
|
||||
|
||||
$title->addHtml(...$headerParts);
|
||||
}
|
||||
|
||||
protected function assembleVisual(BaseHtmlElement $visual): void
|
||||
{
|
||||
$visual->addHtml(new HtmlElement(
|
||||
'div',
|
||||
Attributes::create(['class' => 'user-ball']),
|
||||
Text::create($this->item->author[0])
|
||||
));
|
||||
}
|
||||
|
||||
protected function createTimestamp(): ?BaseHtmlElement
|
||||
{
|
||||
if ($this->item->expire_time) {
|
||||
return Html::tag(
|
||||
'span',
|
||||
FormattedString::create(t("expires %s"), new TimeUntil($this->item->expire_time->getTimestamp()))
|
||||
);
|
||||
}
|
||||
|
||||
return Html::tag(
|
||||
'span',
|
||||
FormattedString::create(t("created %s"), new TimeAgo($this->item->entry_time->getTimestamp()))
|
||||
);
|
||||
}
|
||||
|
||||
protected function init(): void
|
||||
{
|
||||
$this->setTicketLinkEnabled($this->list->getTicketLinkEnabled());
|
||||
$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());
|
||||
}
|
||||
}
|
||||
|
|
@ -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 CommentList extends BaseItemList
|
||||
{
|
||||
use CaptionDisabled;
|
||||
use NoSubjectLink;
|
||||
use ObjectLinkDisabled;
|
||||
use ViewMode;
|
||||
use TicketLinks;
|
||||
use DetailActions;
|
||||
|
||||
protected $defaultAttributes = ['class' => 'comment-list'];
|
||||
|
||||
protected function getItemClass(): string
|
||||
{
|
||||
$viewMode = $this->getViewMode();
|
||||
|
||||
$this->addAttributes(['class' => $viewMode]);
|
||||
|
||||
if ($viewMode === 'minimal') {
|
||||
return CommentListItemMinimal::class;
|
||||
} elseif ($viewMode === 'detailed') {
|
||||
$this->removeAttribute('class', 'default-layout');
|
||||
}
|
||||
|
||||
return CommentListItem::class;
|
||||
}
|
||||
|
||||
protected function init(): void
|
||||
{
|
||||
$this->initializeDetailActions();
|
||||
$this->setMultiselectUrl(Links::commentsDetails());
|
||||
$this->setDetailUrl(Url::fromPath('icingadb/comment'));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2020 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\Widget\ItemList;
|
||||
|
||||
use Icinga\Module\Icingadb\Common\ListItemCommonLayout;
|
||||
|
||||
class CommentListItem extends BaseCommentListItem
|
||||
{
|
||||
use ListItemCommonLayout;
|
||||
}
|
||||
|
|
@ -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 CommentListItemMinimal extends BaseCommentListItem
|
||||
{
|
||||
use ListItemMinimalLayout;
|
||||
|
||||
protected function init(): void
|
||||
{
|
||||
parent::init();
|
||||
|
||||
if ($this->list->isCaptionDisabled()) {
|
||||
$this->setCaptionDisabled();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@ namespace Icinga\Module\Icingadb\Widget\ItemList;
|
|||
|
||||
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\Host;
|
||||
use Icinga\Module\Icingadb\Model\RedundancyGroup;
|
||||
|
|
@ -14,6 +15,7 @@ use Icinga\Module\Icingadb\Model\UnreachableParent;
|
|||
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\HostRenderer;
|
||||
use Icinga\Module\Icingadb\View\RedundancyGroupRenderer;
|
||||
use Icinga\Module\Icingadb\View\ServiceRenderer;
|
||||
|
|
@ -57,9 +59,11 @@ class ObjectList extends ItemList
|
|||
return new UsergroupRenderer();
|
||||
} elseif ($item instanceof User) {
|
||||
return new UserRenderer();
|
||||
} else {
|
||||
throw new NotImplementedError('Not implemented');
|
||||
} elseif ($item instanceof Comment) {
|
||||
return new CommentRenderer();
|
||||
}
|
||||
|
||||
throw new NotImplementedError('Not implemented');
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -190,6 +194,11 @@ class ObjectList extends ItemList
|
|||
case $object instanceof Usergroup || $data instanceof User:
|
||||
$this->addDetailFilterAttribute($item, Filter::equal('name', $object->name));
|
||||
|
||||
break;
|
||||
case $object instanceof Comment:
|
||||
$this->addDetailFilterAttribute($item, Filter::equal('name', $object->name));
|
||||
$this->addMultiSelectFilterAttribute($item, Filter::equal('name', $object->name));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
|||
32
library/Icingadb/Widget/ItemList/TicketLinkObjectList.php
Normal file
32
library/Icingadb/Widget/ItemList/TicketLinkObjectList.php
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2025 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\Widget\ItemList;
|
||||
|
||||
use Icinga\Exception\NotImplementedError;
|
||||
use Icinga\Module\Icingadb\Model\Comment;
|
||||
use Icinga\Module\Icingadb\View\CommentRenderer;
|
||||
use ipl\Orm\Model;
|
||||
use ipl\Web\Widget\ItemList;
|
||||
|
||||
/**
|
||||
* TicketLinkObjectList
|
||||
*
|
||||
* Create a list of icingadb objects with ticket links
|
||||
*
|
||||
* @extends ObjectList //TODO: define object type
|
||||
*/
|
||||
class TicketLinkObjectList extends ObjectList
|
||||
{
|
||||
public function __construct($data)
|
||||
{
|
||||
ItemList::__construct($data, function (Model $item) {
|
||||
if ($item instanceof Comment) {
|
||||
return (new CommentRenderer())->setIsDetailView();
|
||||
}
|
||||
|
||||
throw new NotImplementedError('Not implemented');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -382,16 +382,6 @@ div.show-more {
|
|||
}
|
||||
}
|
||||
|
||||
.comment-popup {
|
||||
.comment-list .main {
|
||||
// This is necessary to limit the visible comment lines
|
||||
// because the popup is shown in detailed list mode only
|
||||
.caption {
|
||||
height: 3em;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
form[name="form_confirm_removal"] {
|
||||
text-align: center;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,50 +0,0 @@
|
|||
// Style
|
||||
|
||||
// Layout
|
||||
|
||||
.comment-list:not(.detailed) .list-item {
|
||||
.title > i:first-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.title > .subject + .badge,
|
||||
.title > .badge + .subject,
|
||||
.title > .badge:last-of-type {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.title a {
|
||||
&:not(.subject) {
|
||||
.text-ellipsis();
|
||||
}
|
||||
}
|
||||
|
||||
.title .subject:not(:last-child) {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.title .subject:nth-child(3):last-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.comment-list.minimal .list-item {
|
||||
.user-ball {
|
||||
font-size: .857em;
|
||||
height: 1.75em;
|
||||
line-height: 1.5em;
|
||||
width: 1.75em;
|
||||
}
|
||||
}
|
||||
|
||||
.comment-list.detailed .list-item {
|
||||
.title > .subject:nth-child(3),
|
||||
.title > .badge + .subject:last-child {
|
||||
margin-left: .3em;
|
||||
}
|
||||
|
||||
.caption {
|
||||
max-height: 4.5em;
|
||||
white-space: normal;
|
||||
}
|
||||
}
|
||||
|
|
@ -35,20 +35,24 @@
|
|||
}
|
||||
}
|
||||
|
||||
ul.item-list li:last-child .comment-wrapper {
|
||||
.comment-popup {
|
||||
top: -7em;
|
||||
}
|
||||
ul.item-list li:nth-last-child(2):not(:first-child),
|
||||
ul.item-list li:last-child:not(:first-child) {
|
||||
.comment-wrapper {
|
||||
.comment-popup {
|
||||
top: -7em;
|
||||
}
|
||||
|
||||
.comment-popup:before {
|
||||
bottom: ~"calc(-0.75em - 1px)";
|
||||
top: unset;
|
||||
transform: rotate(225deg);
|
||||
.comment-popup:before {
|
||||
bottom: ~"calc(-0.75em - 1px)";
|
||||
top: unset;
|
||||
transform: rotate(225deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.comment-wrapper:hover .comment-popup {
|
||||
display: block
|
||||
display: flex;
|
||||
padding: 0 1em;
|
||||
}
|
||||
|
||||
#layout {
|
||||
|
|
@ -72,3 +76,9 @@ ul.item-list li:last-child .comment-wrapper {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.comment-popup .main .caption {
|
||||
// This is necessary to limit the visible comment lines
|
||||
// because the popup is shown in detailed list mode only
|
||||
height: 3em;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue