Quelltext des aktuellen Standes
<?php
use OpenNIT\Core\AuthorColor;
$this->layout('layouts/main', [
'page_title' => $page_title,
'current_route' => $current_route,
'full_width' => true,
'extra_css' => ['/assets/css/teamboard.css'],
]);
/** Zeitpunkt lesbar und mit vollem Wert im Titel. */
$zeit = function (?string $wert): array {
$ts = $wert ? strtotime($wert) : false;
if ($ts === false) {
return ['', ''];
}
return [date('d.m.Y H:i', $ts), date('d.m.Y H:i:s', $ts)];
};
?>
<div class="content-header">
<div>
<h1><i class="fas fa-sticky-note"></i> <?= $this->te('Notizbrett') ?></h1>
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="/"><?= $this->te('Home') ?></a></li>
<li class="breadcrumb-item active"><?= $this->te('Notizbrett') ?></li>
</ol>
</div>
</div>
<div class="page-body">
<div class="kpi-row">
<div class="kpi-col">
<div class="small-box bg-info">
<div class="inner"><h3><?= (int)$gesamt ?></h3><p><?= $this->te('Einträge') ?></p></div>
<div class="icon"><i class="fas fa-sticky-note"></i></div>
</div>
</div>
<div class="kpi-col">
<div class="small-box bg-success">
<div class="inner"><h3><?= (int)$heute ?></h3><p><?= $this->te('Heute') ?></p></div>
<div class="icon"><i class="fas fa-clock"></i></div>
</div>
</div>
<div class="kpi-col">
<div class="small-box bg-primary">
<div class="inner"><h3><?= (int)$eigene ?></h3><p><?= $this->te('Von mir') ?></p></div>
<div class="icon"><i class="fas fa-user"></i></div>
</div>
</div>
<div class="kpi-col">
<div class="small-box bg-warning">
<div class="inner"><h3><?= count($autoren) ?></h3><p><?= $this->te('Beteiligte') ?></p></div>
<div class="icon"><i class="fas fa-users"></i></div>
</div>
</div>
</div>
<div class="card card-outline card-primary mb-3">
<div class="filter-card-body">
<form method="get" action="/teamboard" style="display:flex;gap:0.5rem;flex-wrap:wrap;align-items:center;width:100%;">
<div class="filter-input-wrap" style="flex:1;min-width:200px;">
<svg class="filter-search-icon" viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="7" cy="7" r="5"/><line x1="11" y1="11" x2="14" y2="14"/></svg>
<input type="search" name="q" class="form-control form-control-sm" value="<?= $this->e($suche) ?>" placeholder="<?= $this->te('Notizen durchsuchen …') ?>" aria-label="<?= $this->te('Notizen durchsuchen') ?>">
</div>
<select name="author" class="form-control form-control-sm" style="width:auto;" onchange="this.form.submit()" aria-label="<?= $this->te('Nach Person filtern') ?>">
<option value="0"><?= $this->te('Alle Personen') ?></option>
<?php foreach ($autoren as $a): ?>
<option value="<?= (int)$a['id'] ?>"<?= (int)$autor === (int)$a['id'] ? ' selected' : '' ?>><?= $this->e($a['display_name']) ?></option>
<?php endforeach; ?>
</select>
<button type="submit" class="btn btn-primary btn-sm"><?= $this->te('Filtern') ?></button>
<?php if ($suche !== '' || $autor > 0): ?>
<a href="/teamboard" class="btn btn-default btn-sm"><?= $this->te('Zurücksetzen') ?></a>
<?php endif; ?>
</form>
</div>
</div>
<div class="detail-card tb-compose">
<div class="detail-card-body">
<form method="post" action="/teamboard">
<input type="hidden" name="_csrf" value="<?= $this->csrf() ?>">
<label for="tbBody" class="visually-hidden"><?= $this->te('Text der Notiz') ?></label>
<textarea id="tbBody" name="body" class="form-control form-control-sm"
maxlength="<?= (int)$max_length ?>"
placeholder="<?= $this->te('Was sollte das Team wissen? Zum Beispiel: gestern die Firewall-Regel für den Aussendienst geändert.') ?>"></textarea>
<div class="tb-compose-footer">
<span class="tb-counter"><?= $this->t('Bis zu {max} Zeichen.', ['max' => (int)$max_length]) ?></span>
<button type="submit" class="btn btn-primary btn-sm"><i class="fas fa-paper-plane"></i> <?= $this->te('Eintragen') ?></button>
</div>
</form>
</div>
</div>
<?php if (!$notizen): ?>
<div class="empty-state">
<i class="fas fa-sticky-note"></i>
<p><?= $suche !== '' || $autor > 0
? $this->te('Zu diesem Filter gibt es keine Notizen.')
: $this->te('Noch keine Notizen. Schreib die erste.') ?></p>
</div>
<?php else: ?>
<div class="tb-feed">
<?php foreach ($notizen as $n): ?>
<?php
$uid = (int)($n['created_by'] ?? 0);
$name = (string)($n['display_name'] ?? '');
$anzeige = $name !== '' ? $name : $this->t('Gelöschtes Konto');
[$kurz, $voll] = $zeit($n['created_at'] ?? null);
[$ekurz, $evoll] = $zeit($n['edited_at'] ?? null);
$darf = $uid === (int)$eigene_id || $darf_fremde;
$stil = '--tb-color:' . AuthorColor::css($uid) . ';--tb-soft:' . AuthorColor::softCss($uid) . ';';
?>
<article class="tb-note" style="<?= $this->e($stil) ?>">
<div class="tb-avatar" aria-hidden="true"><?= $this->e(AuthorColor::initials($anzeige)) ?></div>
<div class="tb-main">
<div class="tb-head">
<span class="tb-author"><?= $this->e($anzeige) ?></span>
<span class="tb-time" title="<?= $this->e($voll) ?>"><?= $this->e($kurz) ?></span>
<?php if ($ekurz !== ''): ?>
<span class="tb-edited" title="<?= $this->e($evoll) ?>">· <?= $this->te('bearbeitet') ?></span>
<?php endif; ?>
</div>
<div class="tb-body" id="tbText<?= (int)$n['id'] ?>"><?= $this->e($n['body']) ?></div>
<?php if ($darf): ?>
<div class="tb-actions">
<button type="button" class="btn btn-default btn-sm tb-action"
onclick="tbEdit(<?= (int)$n['id'] ?>)"
title="<?= $this->te('Bearbeiten') ?>" aria-label="<?= $this->te('Bearbeiten') ?>">
<i class="fas fa-pen"></i>
</button>
<form method="post" action="/teamboard/<?= (int)$n['id'] ?>/delete"
onsubmit="return confirm(<?= $this->e(json_encode($this->t('Diese Notiz wirklich löschen?'), JSON_UNESCAPED_UNICODE)) ?>);">
<input type="hidden" name="_csrf" value="<?= $this->csrf() ?>">
<button type="submit" class="btn btn-danger btn-sm tb-action"
title="<?= $this->te('Löschen') ?>" aria-label="<?= $this->te('Löschen') ?>">
<i class="fas fa-trash"></i>
</button>
</form>
</div>
<form method="post" action="/teamboard/<?= (int)$n['id'] ?>" class="tb-edit-form" id="tbForm<?= (int)$n['id'] ?>" style="display:none;">
<input type="hidden" name="_csrf" value="<?= $this->csrf() ?>">
<div class="form-group">
<label for="tbEdit<?= (int)$n['id'] ?>" class="visually-hidden"><?= $this->te('Text der Notiz') ?></label>
<textarea id="tbEdit<?= (int)$n['id'] ?>" name="body" class="form-control form-control-sm" maxlength="<?= (int)$max_length ?>"><?= $this->e($n['body']) ?></textarea>
</div>
<button type="submit" class="btn btn-primary btn-sm"><?= $this->te('Speichern') ?></button>
<button type="button" class="btn btn-default btn-sm" onclick="tbEdit(<?= (int)$n['id'] ?>)"><?= $this->te('Abbrechen') ?></button>
</form>
<?php endif; ?>
</div>
</article>
<?php endforeach; ?>
</div>
<?php if ($seiten > 1): ?>
<nav class="mt-3" aria-label="<?= $this->te('Seiten') ?>">
<?php for ($p = 1; $p <= $seiten; $p++): ?>
<a class="btn btn-sm <?= $p === (int)$seite ? 'btn-primary' : 'btn-default' ?>"
href="/teamboard?page=<?= $p ?>&q=<?= urlencode($suche) ?>&author=<?= (int)$autor ?>"><?= $p ?></a>
<?php endfor; ?>
</nav>
<?php endif; ?>
<?php endif; ?>
</div>
<script>
// Blendet das Bearbeitungsfeld einer Notiz ein und den Text aus.
function tbEdit(id) {
var form = document.getElementById('tbForm' + id);
var text = document.getElementById('tbText' + id);
if (!form || !text) { return; }
var offen = form.style.display !== 'none';
form.style.display = offen ? 'none' : '';
text.style.display = offen ? '' : 'none';
if (!offen) { form.querySelector('textarea').focus(); }
}
</script>