OpenNIT

Quelltext des aktuellen Standes

Fassung 1.1.1

index.php

10 KB
<?php
$this->layout('layouts/main', [
    'page_title'    => $page_title,
    'current_route' => $current_route,
    'full_width'    => true,
    'extra_css'     => ['/assets/css/infrastructure.css?v=' . filemtime(dirname(__DIR__, 2) . '/public/assets/css/infrastructure.css')],
]);
?>

<div class="content-header">
    <div>
        <h1><?= $this->te('Infrastruktur') ?></h1>
        <ol class="breadcrumb">
            <li class="breadcrumb-item"><a href="/"><?= $this->te('Home') ?></a></li>
            <li class="breadcrumb-item active"><?= $this->te('Infrastruktur') ?></li>
        </ol>
    </div>
    <div class="content-header-actions">
        <a href="/infrastructure/cabling" class="btn btn-default btn-sm"><i class="fas fa-network-wired"></i> <?= $this->te('Verkabelungs-Übersicht') ?></a>
        <a href="/infrastructure/free-space" class="btn btn-default btn-sm"><i class="fas fa-ruler-vertical"></i> <?= $this->te('Freien Platz suchen') ?></a>
        <?php if ($can_admin): ?>
        <button type="button" class="btn btn-primary btn-sm" onclick="document.getElementById('inf-rack-modal').style.display='flex'"><i class="fas fa-plus"></i> <?= $this->te('Neues Rack') ?></button>
        <?php endif; ?>
    </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)$kpis['sites'] ?></h3><p><?= $this->te('Standorte mit Racks') ?></p></div><span class="icon"><i class="fas fa-map-marker-alt"></i></span></div></div>
        <div class="kpi-col"><div class="small-box bg-primary"><div class="inner"><h3><?= (int)$kpis['racks'] ?></h3><p><?= $this->te('Racks') ?></p></div><span class="icon"><i class="fas fa-server"></i></span></div></div>
        <div class="kpi-col"><div class="small-box bg-success"><div class="inner"><h3><?= (int)$kpis['devices'] ?></h3><p><?= $this->te('Geräte verbaut') ?></p></div><span class="icon"><i class="fas fa-plug"></i></span></div></div>
        <div class="kpi-col"><div class="small-box <?= (int)$kpis['offline'] > 0 ? 'bg-danger' : 'bg-secondary' ?>"><div class="inner"><h3><?= (int)$kpis['offline'] ?></h3><p><?= $this->te('Offline') ?></p></div><span class="icon"><i class="fas fa-exclamation-triangle"></i></span></div></div>
    </div>

    <div class="card card-outline card-primary mb-3">
        <div class="filter-card-body">
            <form method="GET" action="/infrastructure" class="filter-input-wrap" style="max-width:420px;">
                <span class="filter-search-icon">&#128269;</span>
                <input type="search" name="q" class="form-control form-control-sm" value="<?= $this->e($q ?? '') ?>"
                       placeholder="<?= $this->te('Gerät, Inventar-Nr., MAC, Modell oder Port-Beschriftung…') ?>" autocomplete="off" autofocus>
            </form>
            <?php if (($q ?? '') !== ''): ?>
                <a href="/infrastructure" class="btn btn-sm btn-default"><?= $this->te('Zurücksetzen') ?></a>
            <?php endif; ?>
        </div>
    </div>

    <?php if ($searchResults !== null): ?>
        <h2 class="inf-section-title"><i class="fas fa-search"></i> <?= $this->te('Suchergebnisse') ?> <span class="inf-hint">– <?= count($searchResults) ?> Treffer für „<?= $this->e($q) ?>"</span></h2>
        <?php if (empty($searchResults)): ?>
            <div class="empty-state"><div class="empty-icon"><i class="fas fa-search"></i></div><h2><?= $this->te('Keine Treffer') ?></h2><p><?= $this->t('Kein eingebautes Gerät passt zu „') ?><?= $this->e($q) ?>".</p></div>
        <?php else: ?>
            <div class="table-wrapper">
                <table class="data-table">
                    <thead><tr><th scope="col"><?= $this->te('Gerät') ?></th><th scope="col"><?= $this->te('Standort') ?></th><th scope="col"><?= $this->te('Rack') ?></th><th scope="col"><?= $this->te('Treffer') ?></th></tr></thead>
                    <tbody>
                    <?php foreach ($searchResults as $r): ?>
                        <tr>
                            <td><a href="/infrastructure/racks/<?= (int)$r['rack_id'] ?>" class="table-link"><strong><?= $this->e($r['name']) ?></strong></a></td>
                            <td><?= $this->e($r['location']) ?: '<span class="text-muted">–</span>' ?></td>
                            <td><?= $this->e($r['rack']) ?></td>
                            <td><?= $r['hint'] !== '' ? '<span class="text-muted">' . $this->e($r['hint']) . '</span>' : '<span class="text-muted">–</span>' ?></td>
                        </tr>
                    <?php endforeach; ?>
                    </tbody>
                </table>
            </div>
        <?php endif; ?>
    <?php elseif (empty($sites)): ?>
        <div class="empty-state">
            <div class="empty-icon"><i class="fas fa-server"></i></div>
            <h2><?= $this->te('Noch keine Infrastruktur dokumentiert') ?></h2>
            <p><?= $this->te('Legen Sie Ihr erstes Rack an und wählen Sie dabei den Standort. Danach erscheint der Standort hier in der Übersicht.') ?></p>
            <?php if ($can_admin): ?>
                <button type="button" class="btn btn-primary" onclick="document.getElementById('inf-rack-modal').style.display='flex'"><i class="fas fa-plus"></i> <?= $this->te('Neues Rack anlegen') ?></button>
            <?php endif; ?>
        </div>
    <?php else: ?>
        <h2 class="inf-section-title"><i class="fas fa-map-marker-alt"></i> <?= $this->te('Standorte') ?> <span class="inf-hint"><?= $this->te('– nur Standorte mit Racks') ?></span></h2>
        <div class="inf-site-grid">
            <?php foreach ($sites as $s): $loc = $s['location']; ?>
            <a class="inf-site-card" href="/infrastructure/locations/<?= (int)$loc['id'] ?>">
                <div class="inf-site-top">
                    <span class="inf-site-ic"><i class="fas fa-building"></i></span>
                    <span class="inf-site-nm"><?= $this->e($loc['name']) ?></span>
                </div>
                <div class="inf-site-stats">
                    <div class="st"><span class="n"><?= (int)$s['racks'] ?></span><span class="l"><?= $this->te('Racks') ?></span></div>
                    <div class="st"><span class="n"><?= (int)$s['devices'] ?></span><span class="l"><?= $this->te('Geräte') ?></span></div>
                </div>
                <div class="inf-site-foot">
                    <?php if ((int)$s['offline'] > 0): ?>
                        <span class="status-pill status-pill--danger"><span class="status-dot status-dot--danger"></span> <?= (int)$s['offline'] ?> offline</span>
                    <?php else: ?>
                        <span class="status-pill status-pill--success"><span class="status-dot status-dot--success"></span> <?= $this->te('online') ?></span>
                    <?php endif; ?>
                </div>
            </a>
            <?php endforeach; ?>
        </div>
    <?php endif; ?>

</div>

<?php if ($can_admin): ?>
<div class="modal-overlay" id="inf-rack-modal" style="display:none;" onclick="if(event.target===this)this.style.display='none'">
    <div class="modal-card">
        <div class="modal-header"><h2><?= $this->te('Neues Rack anlegen') ?></h2>
            <button aria-label="<?= $this->te('Schließen') ?>" type="button" class="modal-close" onclick="document.getElementById('inf-rack-modal').style.display='none'">&times;</button></div>
        <form method="POST" action="/infrastructure/racks">
            <input type="hidden" name="_csrf" value="<?= $this->csrf() ?>">
            <div class="modal-body">
                <div class="form-group">
                    <label for="f-fefb-location_id"><?= $this->te('Standort') ?> <span class="text-danger">*</span></label>
                    <select id="f-fefb-location_id" name="location_id" class="form-control form-control-sm" required data-searchable>
                        <option value=""><?= $this->te('— Standort wählen —') ?></option>
                        <?php foreach ($locationOptions as $o): ?>
                            <option value="<?= (int)$o['id'] ?>" data-depth="<?= (int)$o['depth'] ?>"><?= str_repeat('&nbsp;&nbsp;', (int)$o['depth']) ?><?= $this->e($o['name']) ?></option>
                        <?php endforeach; ?>
                    </select>
                    <?php if (empty($locationOptions)): ?>
                        <small class="form-text text-muted"><?= $this->te('Es sind noch keine Standorte angelegt. Legen Sie zuerst unter „Standorte" (Tickets/Inventar) einen Standort an.') ?></small>
                    <?php endif; ?>
                </div>
                <div class="form-group">
                    <label><?= $this->te('Name') ?> <span class="text-danger">*</span></label>
                    <input type="text" name="name" class="form-control form-control-sm" placeholder="<?= $this->te('z. B. SRV-01') ?>" required>
                </div>
                <div class="inf-form-row-2">
                    <div class="form-group"><label for="f-fefb-height_u"><?= $this->te('Höhe (HE)') ?></label><input id="f-fefb-height_u" type="number" name="height_u" class="form-control form-control-sm" value="42" min="1" max="60"></div>
                    <div class="form-group"><label for="f-fefb-numbering"><?= $this->te('Nummerierung') ?></label>
                        <select id="f-fefb-numbering" name="numbering" class="form-control form-control-sm">
                            <option value="bottom_up"><?= $this->te('von unten (1 unten)') ?></option>
                            <option value="top_down"><?= $this->te('von oben (1 oben)') ?></option>
                        </select>
                    </div>
                </div>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-default" onclick="document.getElementById('inf-rack-modal').style.display='none'"><?= $this->te('Abbrechen') ?></button>
                <button type="submit" class="btn btn-primary"><?= $this->te('Rack anlegen') ?></button>
            </div>
        </form>
    </div>
</div>
<script>
document.addEventListener('keydown', function(e){
    if(e.key==='Escape'){ var m=document.getElementById('inf-rack-modal'); if(m) m.style.display='none'; }
});
</script>
<?php endif; ?>