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

@ -3,16 +3,45 @@
</div>
<div class="content styleguide">
<div class="section">
<h1>Icinga Web 2 Design Guidelines</h1>
<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>
<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>
<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>
<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>
<table class="avp">
<div class="section">
<h2 id="tables">Tables</h2>
<table class="common-table">
<thead>
<tr>
<th>Table Head - th in thead</th>
@ -34,7 +63,42 @@
</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.
@ -45,3 +109,4 @@
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,16 +11,20 @@
</div>
<?php endif ?>
<div class="content">
<?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-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)); ?>
<?= $this->partial('partials/comment/comment-description.phtml', array('comment' => $comment)) ?>
</td>
<td>
<?= $this->partial(
@ -34,17 +38,17 @@
<?php endforeach ?>
</tbody>
</table>
<?php if (! $comments->hasResult()): ?>
<?= $this->translate('No comments found matching the filter'); ?>
<?php elseif ($comments->hasMore()): ?>
<?php if ($comments->hasMore()): ?>
<div class="action-links">
<?= $this->qlink(
$this->translate('Show More'),
$this->url()->without(array('view', 'limit')),
null,
array(
'data-base-target' => '_next',
'class' => 'pull-right action-link'
'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,6 +1,7 @@
<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(
@ -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,13 +28,14 @@
$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">
</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.'),
@ -51,8 +54,7 @@
echo $deleteButton;
} ?>
</span>
</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,10 +38,11 @@
)
); ?>
<?php endif ?>
<span class="comment-meta">
<span class="comment-time">
<?= $this->translate('by') ?>
<?= $this->escape($downtime->author_name) ?>
<span class="meta-icons">
</span>
<span class="comment-icons">
<?php if ($downtime->is_flexible): ?>
<?= $this->icon('magic', $this->translate('This downtime is flexible')); ?>
<?php endif ?>
@ -50,8 +51,8 @@
<?= $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
<?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');
@ -62,12 +63,10 @@
)
);
echo $deleteButton;
?>
<?php endif ?>
</span>
} ?>
</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):

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
<?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;
?>
</span>
<?php endif ?>
</span>
} ?>
</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,14 +45,15 @@ 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
</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');
@ -63,13 +64,10 @@ if (empty($object->comments) && ! $addLink) {
)
);
echo $deleteButton;
?>
</span>
<?php endif ?>
</span>
} ?>
</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,16 +73,16 @@ 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
</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');
@ -93,13 +93,10 @@ if (empty($object->comments) && ! $addLink) {
)
);
echo $deleteButton;
?>
</span>
<?php endif ?>
</span>
} ?>
</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;
}
}
> dd {
margin: 0 0 1em 0;
}
}
.comment-header {
.clearfix();
}
.comment-meta {
.comment-time {
color: @text-color-light;
font-size: @font-size-small;
> .meta-icons {
float: right;
margin-top: 0.2em;
}
}
.comment-text {
// Reset margin
margin: 0;
}
.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;