Merge branch 'bugfix/line-breaks-in-comments-10603'

fixes #10603
This commit is contained in:
Eric Lippmann 2015-12-21 09:39:12 +01:00
commit 11e7d1050f
14 changed files with 287 additions and 205 deletions

View File

@ -6,3 +6,7 @@ use Icinga\Util\String;
$this->addHelperFunction('ellipsis', function ($string, $maxLength, $ellipsis = '...') {
return String::ellipsis($string, $maxLength, $ellipsis);
});
$this->addHelperFunction('nl2br', function ($string) {
return str_replace(array('\r\n', '\r', '\n'), '<br>', $string);
});

View File

@ -1,47 +1,112 @@
<div class="controls">
<?= $this->tabs ?>
<?= $this->tabs ?>
</div>
<div class="content styleguide">
<h1>Header h1</h1>
<h2>Header h2</h2>
<h3>Header h3</h3>
<h4>Header h4</h4>
<h5>Header h5</h5>
<h6>Header h6</h6>
<div class="section">
<h1>Icinga Web 2 Design Guidelines</h1>
<p>This is a paragraph. This is a paragraph. This is a paragraph. This is a paragraph. This is a paragraph. This is a paragraph. A <a href="#">link pointing somewhere</a>. This is a paragraph. This is a paragraph. This is a paragraph. This is a paragraph. This is a paragraph.</p>
<ul class="toc">
<li><a href="#headings">Headings</a></li>
<li><a href="#block-content">Block Content</a></li>
<li><a href="#tables">Tables</a></li>
<li><a href="#comment-list">Comment List</a></li>
<li><a href="#blockquote">Blockquote</a></li>
</ul>
</div>
<table class="avp">
<thead>
<tr>
<th>Table Head - th in thead</th>
<td>td in thead<td>
</tr>
</thead>
<tbody>
<tr>
<th>Tbody - th</th>
<td>Tbody - td</td>
</tr>
<tr>
<th>Tbody - th</th>
<td>Tbody - td</td>
</tr>
<tr>
<th>Tbody - th</th>
<td>Tbody - td</td>
</tr>
</tbody>
</table>
<div class="section">
<h2 id="headings">Headings</h2>
<h1>Header h1</h1>
<h2>Header h2</h2>
<h3>Header h3</h3>
<h4>Header h4</h4>
<h5>Header h5</h5>
<h6>Header h6</h6>
</div>
<blockquote>
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor
invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren,
no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet,
consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore
magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum.
Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
</blockquote>
<div class="section">
<h2 id="block-content">Block Content</h2>
<h3>Paragraph</h3>
<p>
This is a paragraph. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor
invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo
dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
A <a href="#">link inside a paragraph</a>.
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et
dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum.
Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
</p>
</div>
<div class="section">
<h2 id="tables">Tables</h2>
<table class="common-table">
<thead>
<tr>
<th>Table Head - th in thead</th>
<td>td in thead<td>
</tr>
</thead>
<tbody>
<tr>
<th>Tbody - th</th>
<td>Tbody - td</td>
</tr>
<tr>
<th>Tbody - th</th>
<td>Tbody - td</td>
</tr>
<tr>
<th>Tbody - th</th>
<td>Tbody - td</td>
</tr>
</tbody>
</table>
</div>
<div class="section">
<h2 id="comment-list"><?= $this->translate('Comment List') ?></h2>
<dl class="comment-list">
<dt>
John Doe
<span class="comment-time">
<?= $this->translate('commented') ?>
<span class="relative-time"><?= $this->translate('some time ago') ?></span>
</span>
<i class="remove-action icon-cancel"></i>
</dt>
<dd>
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore
<br>
et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum.
</dd>
<dt>
Richard Roe
<span class="comment-time">
<?= $this->translate('commented') ?>
<span class="relative-time"><?= $this->translate('some time ago') ?></span>
</span>
<i class="remove-action icon-cancel"></i>
</dt>
<dd>
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore
<br>
et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum.
</dd>
</dl>
</div>
<div class="section">
<h2 id="blockquote"><?= $this->translate('Blockquote') ?></h2>
<blockquote>
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor
invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren,
no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet,
consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore
magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum.
Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
</blockquote>
</div>
</div>

View File

@ -45,7 +45,7 @@
</tr>
<tr title="<?= $this->translate('A comment, as entered by the author, associated with the scheduled downtime'); ?>">
<th><?= $this->translate('Comment') ?></th>
<td class="comment-text"><?= $this->escape($this->downtime->comment) ?></td>
<td class="comment-text"><?= $this->nl2br($this->escape($this->downtime->comment)) ?></td>
</tr>
</tbody>
</table>

View File

@ -1,5 +1,5 @@
<?php if (! $this->compact): ?>
<div class="controls separated">
<div class="controls">
<?= $tabs ?>
<?= $this->render('list/components/selectioninfo.phtml') ?>
<div class="grid">
@ -11,40 +11,44 @@
</div>
<?php endif ?>
<div class="content">
<table data-base-target="_next"
class="table-row-selectable common-table multiselect"
data-icinga-multiselect-url="<?= $this->href('monitoring/comments/show'); ?>"
data-icinga-multiselect-related="<?= $this->href("monitoring/comments") ?>"
data-icinga-multiselect-data="comment_id">
<?php if (! $comments->hasResult()): ?>
<p><?= $this->translate('No comments found matching the filter') ?></p>
</div>
<?php return; endif ?>
<table data-base-target="_next"
class="table-row-selectable common-table multiselect"
data-icinga-multiselect-url="<?= $this->href('monitoring/comments/show') ?>"
data-icinga-multiselect-related="<?= $this->href("monitoring/comments") ?>"
data-icinga-multiselect-data="comment_id">
<tbody>
<?php foreach ($comments->peekAhead($this->compact) as $comment): ?>
<tr href="<?= $this->href('monitoring/comment/show', array('comment_id' => $comment->id)) ?>">
<td class="icon-col">
<?= $this->partial('partials/comment/comment-description.phtml', array('comment' => $comment)); ?>
</td>
<td>
<?= $this->partial(
'partials/comment/comment-detail.phtml',
array(
'comment' => $comment,
'delCommentForm' => $delCommentForm // Form is unset if the current user lacks the respective permission
)) ?>
</td>
</tr>
<tr href="<?= $this->href('monitoring/comment/show', array('comment_id' => $comment->id)) ?>">
<td class="icon-col">
<?= $this->partial('partials/comment/comment-description.phtml', array('comment' => $comment)) ?>
</td>
<td>
<?= $this->partial(
'partials/comment/comment-detail.phtml',
array(
'comment' => $comment,
'delCommentForm' => $delCommentForm // Form is unset if the current user lacks the respective permission
)) ?>
</td>
</tr>
<?php endforeach ?>
</tbody>
</table>
<?php if (! $comments->hasResult()): ?>
<?= $this->translate('No comments found matching the filter'); ?>
<?php elseif ($comments->hasMore()): ?>
<?= $this->qlink(
$this->translate('Show More'),
$this->url()->without(array('view', 'limit')),
null,
array(
'data-base-target' => '_next',
'class' => 'pull-right action-link'
)
); ?>
</table>
<?php if ($comments->hasMore()): ?>
<div class="action-links">
<?= $this->qlink(
$this->translate('Show More'),
$this->url()->without(array('view', 'limit')),
null,
array(
'class' => 'action-link',
'data-base-target' => '_next'
)
) ?>
</div>
<?php endif ?>
</div>

View File

@ -16,7 +16,7 @@ if (! $this->compact): ?>
<?php endif ?>
<div class="content">
<table data-base-target="_next"
class="table-row-selectable state-table multiselect"
class="table-row-selectable state-table multiselect common-table"
data-icinga-multiselect-url="<?= $this->href('monitoring/downtimes/show'); ?>"
data-icinga-multiselect-controllers="<?= $this->href("monitoring/downtimes") ?>"
data-icinga-multiselect-data="downtime_id">

View File

@ -1,10 +1,11 @@
<div class="comment-header">
<?php if ($comment->objecttype === 'service'): ?>
<?= $this->icon('service', $this->translate('Service')) ?> <?= $this->qlink(
<div class="comment-author">
<?php if ($comment->objecttype === 'service') {
echo $this->icon('service', $this->translate('Service'));
echo $this->qlink(
$comment->host_display_name . ': ' . $comment->service_display_name,
'monitoring/service/show',
array(
'host' => $comment->host_name,
'host' => $comment->host_name,
'service' => $comment->service_description
),
array(
@ -14,9 +15,10 @@
$comment->host_display_name
)
)
) ?>
<?php else: ?>
<?= $this->icon('host', $this->translate('Host')) ?> <?= $this->qlink(
);
} else {
echo $this->icon('host', $this->translate('Host'));
echo $this->qlink(
$comment->host_display_name,
'monitoring/host/show',
array('host' => $comment->host_name),
@ -26,33 +28,33 @@
$comment->host_display_name
)
)
) ?>
<?php endif ?>
<span class="comment-meta">
);
} ?>
<span class="comment-time">
<?= $this->translate('by') ?>
<?= $this->escape($comment->author) ?>
<?= $this->timeAgo($comment->timestamp) ?>
<span class="meta-icons" data-base-target="_self">
<?= $comment->persistent ? $this->icon('attach', 'This comment is persistent.') : '' ?>
<?= $comment->expiration ? $this->icon('clock', sprintf(
$this->translate('This comment expires %s.'),
$this->timeUntil($comment->expiration)
)) : '' ?>
<?php if (isset($delCommentForm)) {
$deleteButton = clone $delCommentForm;
/** @var \Icinga\Module\Monitoring\Forms\Command\Object\DeleteCommentCommandForm $deleteButton */
$deleteButton->setAttrib('class', $deleteButton->getAttrib('class') . ' remove-action');
$deleteButton->populate(
array(
'comment_id' => $comment->id,
'comment_is_service' => isset($comment->service_description)
)
);
echo $deleteButton;
} ?>
</span>
</span>
<span class="comment-icons" data-base-target="_self">
<?= $comment->persistent ? $this->icon('attach', 'This comment is persistent.') : '' ?>
<?= $comment->expiration ? $this->icon('clock', sprintf(
$this->translate('This comment expires %s.'),
$this->timeUntil($comment->expiration)
)) : '' ?>
<?php if (isset($delCommentForm)) {
$deleteButton = clone $delCommentForm;
/** @var \Icinga\Module\Monitoring\Forms\Command\Object\DeleteCommentCommandForm $deleteButton */
$deleteButton->setAttrib('class', $deleteButton->getAttrib('class') . ' remove-action');
$deleteButton->populate(
array(
'comment_id' => $comment->id,
'comment_is_service' => isset($comment->service_description)
)
);
echo $deleteButton;
} ?>
</span>
</div>
<p class="comment-text">
<?= $this->escape($comment->comment) ?>
<?= $this->nl2br($this->escape($comment->comment)) ?>
</p>

View File

@ -8,7 +8,7 @@
<?php endif; ?>
</td>
<td>
<div class="comment-header">
<div class="comment-author">
<?php if ($isService): ?>
<?= $this->icon('service', $this->translate('Service')); ?> <?= $this->qlink(
$downtime->host_display_name . ': ' . $downtime->service_display_name,
@ -38,36 +38,35 @@
)
); ?>
<?php endif ?>
<span class="comment-meta">
<span class="comment-time">
<?= $this->translate('by') ?>
<?= $this->escape($downtime->author_name) ?>
<span class="meta-icons">
<?php if ($downtime->is_flexible): ?>
<?= $this->icon('magic', $this->translate('This downtime is flexible')); ?>
<?php endif ?>
</span>
<span class="comment-icons">
<?php if ($downtime->is_flexible): ?>
<?= $this->icon('magic', $this->translate('This downtime is flexible')); ?>
<?php endif ?>
<?php if ($downtime->is_in_effect): ?>
<?= $this->icon('plug', $this->translate('This downtime is in effect')); ?>
<?php endif ?>
<?php if ($downtime->is_in_effect): ?>
<?= $this->icon('plug', $this->translate('This downtime is in effect')); ?>
<?php endif ?>
<?php if (isset($delDowntimeForm)): // Form is unset if the current user lacks the respective permission ?>
<?php
$deleteButton = clone $delDowntimeForm;
/** @var \Icinga\Module\Monitoring\Forms\Command\Object\DeleteDowntimeCommandForm $deleteButton */
$deleteButton->setAttrib('class', $deleteButton->getAttrib('class') . ' remove-action');
$deleteButton->populate(
array(
'downtime_id' => $downtime->id,
'downtime_is_service' => isset($downtime->service_description)
)
);
echo $deleteButton;
?>
<?php endif ?>
</span>
<?php if (isset($delDowntimeForm)) {
// Form is unset if the current user lacks the respective permission
$deleteButton = clone $delDowntimeForm;
/** @var \Icinga\Module\Monitoring\Forms\Command\Object\DeleteDowntimeCommandForm $deleteButton */
$deleteButton->setAttrib('class', $deleteButton->getAttrib('class') . ' remove-action');
$deleteButton->populate(
array(
'downtime_id' => $downtime->id,
'downtime_is_service' => isset($downtime->service_description)
)
);
echo $deleteButton;
} ?>
</span>
</div>
<p class="comment-text">
<?= $this->escape($downtime->comment) ?>
<?= $this->nl2br($this->escape($downtime->comment)) ?>
</p>
</td>

View File

@ -2,7 +2,7 @@
use Icinga\Module\Monitoring\Object\Host;
use Icinga\Module\Monitoring\Object\Service;
?>
<table class="action" data-base-target="_next">
<table class="state-table common-table" data-base-target="_next">
<tbody>
<?php
foreach ($this->downtimes as $i => $downtime):
@ -37,4 +37,4 @@ use Icinga\Module\Monitoring\Object\Service;
)
) ?>
</p>
<?php endif ?>
<?php endif ?>

View File

@ -16,9 +16,9 @@ $acknowledgement = $object->acknowledgement;
<td data-base-target="_self">
<?php if ($acknowledgement): ?>
<dl class="comment-list">
<dt class="comment-header">
<dt>
<?= $this->escape($acknowledgement->getAuthor()) ?>
<span class="comment-meta">
<span class="comment-time">
<?= $this->translate('acknowledged') ?>
<?= $this->timeAgo($acknowledgement->getEntryTime()) ?>
<?php if ($acknowledgement->expires()): ?>
@ -28,6 +28,7 @@ $acknowledgement = $object->acknowledgement;
$this->timeUntil($acknowledgement->getExpirationTime())
) ?>
<?php endif ?>
</span>
<?php if ($acknowledgement->getSticky()): ?>
<?= $this->icon('pin', sprintf(
$this->translate(
@ -36,18 +37,14 @@ $acknowledgement = $object->acknowledgement;
$object->getType(true)
)) ?>
<?php endif ?>
<?php if (isset($removeAckForm)): // Form is unset if the current user lacks the respective permission ?>
<span class="meta-icons">
<?php
$removeAckForm->setAttrib('class', $removeAckForm->getAttrib('class') . ' remove-action');
echo $removeAckForm;
?>
</span>
<?php endif ?>
</span>
<?php if (isset($removeAckForm)) {
// Form is unset if the current user lacks the respective permission
$removeAckForm->setAttrib('class', $removeAckForm->getAttrib('class') . ' remove-action');
echo $removeAckForm;
} ?>
</dt>
<dd class="comment-text">
<p><?= nl2br($this->createTicketLinks($this->escape($acknowledgement->getComment())), false) ?></p>
<dd>
<?= $this->nl2br($this->createTicketLinks($this->escape($acknowledgement->getComment()))) ?>
</dd>
</dl>
<?php else: ?>
@ -88,7 +85,7 @@ $acknowledgement = $object->acknowledgement;
'Acknowledge this problem, suppress all future notifications for it and tag it as being handled'
)
)
); ?>
) ?>
<?php } else {
echo '&#45;';
} // endif ?>

View File

@ -45,31 +45,29 @@ if (empty($object->comments) && ! $addLink) {
else: ?>
<dl class="comment-list">
<?php foreach ($object->comments as $comment): ?>
<dt class="comment-header">
<dt>
<?= $this->escape($comment->author) ?>
<span class="comment-meta">
<span class="comment-time">
<?= $this->translate('commented') ?>
<?= $this->timeAgo($comment->timestamp) ?>
<?php if (isset($delCommentForm)): // Form is unset if the current user lacks the respective permission ?>
<span class="meta-icons">
<?php
$deleteButton = clone($delCommentForm);
/** @var \Icinga\Module\Monitoring\Forms\Command\Object\DeleteCommentCommandForm $deleteButton */
$deleteButton->setAttrib('class', $deleteButton->getAttrib('class') . ' remove-action');
$deleteButton->populate(
array(
'comment_id' => $comment->id,
'comment_is_service' => isset($comment->service_description)
)
);
echo $deleteButton;
?>
</span>
<?php endif ?>
</span>
<?= $comment->persistent ? $this->icon('attach', 'This comment is persistent.') : '' ?>
<?php if (isset($delCommentForm)) {
// Form is unset if the current user lacks the respective permission
$deleteButton = clone($delCommentForm);
/** @var \Icinga\Module\Monitoring\Forms\Command\Object\DeleteCommentCommandForm $deleteButton */
$deleteButton->setAttrib('class', $deleteButton->getAttrib('class') . ' remove-action');
$deleteButton->populate(
array(
'comment_id' => $comment->id,
'comment_is_service' => isset($comment->service_description)
)
);
echo $deleteButton;
} ?>
</dt>
<dd class="comment-text">
<p><?= nl2br($this->createTicketLinks($this->escape($comment->comment)), false) ?></p>
<dd>
<?= $this->nl2br($this->createTicketLinks($this->escape($comment->comment))) ?>
</dd>
<?php endforeach ?>
</dl>

View File

@ -73,33 +73,30 @@ if (empty($object->comments) && ! $addLink) {
}
}
?>
<dt class="comment-header">
<dt>
<?= $this->escape($downtime->author_name) ?>
<span class="comment-meta">
<span class="comment-time">
<?= $this->translate('created') ?>
<?= $this->timeAgo($downtime->entry_time) ?>
<span aria-hidden="true">&#448;</span>
<?= $state ?>
<?php if (isset($delDowntimeForm)): // Form is unset if the current user lacks the respective permission ?>
<span class="meta-icons">
<?php
$deleteButton = clone($delDowntimeForm);
/** @var \Icinga\Module\Monitoring\Forms\Command\Object\DeleteDowntimeCommandForm $deleteButton */
$deleteButton->setAttrib('class', $deleteButton->getAttrib('class') . ' remove-action');
$deleteButton->populate(
array(
'downtime_id' => $downtime->id,
'downtime_is_service' => $object->getType() === $object::TYPE_SERVICE
)
);
echo $deleteButton;
?>
</span>
<?php endif ?>
</span>
<?php if (isset($delDowntimeForm)) {
// Form is unset if the current user lacks the respective permission
$deleteButton = clone($delDowntimeForm);
/** @var \Icinga\Module\Monitoring\Forms\Command\Object\DeleteDowntimeCommandForm $deleteButton */
$deleteButton->setAttrib('class', $deleteButton->getAttrib('class') . ' remove-action');
$deleteButton->populate(
array(
'downtime_id' => $downtime->id,
'downtime_is_service' => $object->getType() === $object::TYPE_SERVICE
)
);
echo $deleteButton;
} ?>
</dt>
<dd class="comment-text">
<p><?= nl2br($this->createTicketLinks($this->escape($downtime->comment)), false) ?></p>
<dd>
<?= $this->nl2br($this->createTicketLinks($this->escape($downtime->comment))) ?>
</dd>
<?php endforeach ?>
</dl>

View File

@ -322,6 +322,7 @@ abstract class MonitoredObject implements Filterable
'comment' => 'comment_data',
'expiration' => 'comment_expiration',
'id' => 'comment_internal_id',
'persistent' => 'comment_is_persistent',
'timestamp' => 'comment_timestamp',
'type' => 'comment_type'
));

View File

@ -7,6 +7,22 @@
font-size: @font-size-small;
}
// Object link and comment author in the comment overview
.comment-author {
margin-bottom: 0.25em;
}
// Comment icons, e.g. persistent in the comment overview
.comment-icons {
float: right;
}
// Comment text in the comment overview
.comment-text {
// Reset margin
margin: 0;
}
// Type information for backends in the monitoring config
.config-label-meta {
font-size: @font-size-small;

View File

@ -56,6 +56,10 @@
}
}
.section {
margin-bottom: 2em;
}
a:hover > .icon-cancel {
color: @color-critical;
}
@ -88,49 +92,40 @@ a:hover > .icon-cancel {
.comment-list {
margin: 0;
.comment-header {
> dt {
border-bottom: 1px solid @gray-lighter;
margin-bottom: 0.25em;
&:hover {
background-color: @gray-lightest;
> .comment-meta > .meta-icons > .remove-action {
> .remove-action {
visibility: visible;
}
}
> .comment-meta > .meta-icons > .remove-action {
> .remove-action {
visibility: hidden;
}
}
}
.comment-header {
.clearfix();
}
.comment-meta {
color: @text-color-light;
font-size: @font-size-small;
> .meta-icons {
float: right;
margin-top: 0.2em;
> dd {
margin: 0 0 1em 0;
}
}
.comment-text {
// Reset margin
margin: 0;
.comment-time {
color: @text-color-light;
font-size: @font-size-small;
}
.name-value-list {
dd {
> dd {
// Reset default margin
margin: 0;
}
dt {
> dt {
color: @text-color-light;
font-size: @font-size-small;
}
@ -190,7 +185,11 @@ a:hover > .icon-cancel {
}
}
.name-value-table th {
.name-value-table {
width: 100%;
}
.name-value-table > tbody > tr > th {
color: @text-color-light;
// Reset default font-weight
font-weight: normal;