feat: add NetBox plugin store
CI / php-store (push) Canceled after 0s
CI / python-components (push) Canceled after 0s

This commit is contained in:
2026-08-24 20:51:25 +02:00
commit f36d6be511
135 changed files with 15160 additions and 0 deletions
+98
View File
@@ -0,0 +1,98 @@
<?php declare(strict_types=1); include __DIR__ . '/partials/head.php'; ?>
<section class="hero">
<div class="shell hero-grid">
<div>
<span class="eyebrow">Kuratierter Katalog</span>
<h1>Plugins, auf die dein<br><span>NetBox vertrauen kann.</span></h1>
<p class="hero-copy">Entdecke freigegebene Erweiterungen aus unseren Forgejo-Repositories. Jede Version wird separat geprüft, gehasht und erst nach einer Admin-Freigabe installierbar.</p>
</div>
<div class="hero-stat" aria-label="Katalogstatistik">
<strong><?= $e($totalCount ?? 0) ?></strong>
<span>freigegebene Plugins</span>
<small>Metadaten commitgenau synchronisiert</small>
</div>
</div>
</section>
<section class="shell catalog-section">
<form class="filter-panel" method="get" action="/">
<label class="search-field">
<span>Plugins durchsuchen</span>
<input type="search" name="q" value="<?= $e($query ?? '') ?>" placeholder="Name, Paket oder Beschreibung …">
</label>
<label>
<span>Quelle</span>
<select name="source">
<option value="">Alle Quellen</option>
<?php foreach (($sources ?? []) as $filterSource): ?>
<option value="<?= $e($filterSource['slug']) ?>" <?= ($selectedSource ?? '') === $filterSource['slug'] ? 'selected' : '' ?>><?= $e($filterSource['name']) ?></option>
<?php endforeach; ?>
</select>
</label>
<label>
<span>NetBox-Version</span>
<input name="netbox_version" value="<?= $e($selectedNetboxVersion ?? '') ?>" placeholder="z. B. 4.6.5" inputmode="decimal">
</label>
<button class="button primary" type="submit">Filtern</button>
<?php if (($query ?? '') !== '' || ($selectedSource ?? '') !== '' || ($selectedNetboxVersion ?? '') !== ''): ?>
<a class="button quiet" href="/">Zurücksetzen</a>
<?php endif; ?>
</form>
<?php if (!empty($invalidVersion)): ?>
<p class="notice error">Die angegebene NetBox-Version ist ungültig. Der Versionsfilter wurde ignoriert.</p>
<?php endif; ?>
<div class="catalog-heading">
<div>
<span class="eyebrow">Store</span>
<h2><?= $e($count ?? 0) ?> <?= ($count ?? 0) === 1 ? 'Plugin' : 'Plugins' ?></h2>
</div>
<span class="muted">Nur freigegebene Katalogeinträge</span>
</div>
<?php if (($plugins ?? []) === []): ?>
<div class="empty-state">
<span class="empty-icon" aria-hidden="true">⌁</span>
<h2>Keine Plugins gefunden</h2>
<p>Ändere die Suche oder den Versionsfilter. Neu eingelesene Plugins erscheinen erst nach der Freigabe.</p>
</div>
<?php else: ?>
<div class="plugin-grid">
<?php foreach ($plugins as $plugin): ?>
<?php $release = $plugin['latestRelease'] ?? null; $isWheel = is_array($release) && ($release['artifactKind'] ?? '') === 'wheel'; ?>
<article class="plugin-card">
<div class="card-topline">
<span class="provider-pill"><?= $e(strtoupper((string) ($plugin['source']['provider'] ?? 'git'))) ?></span>
<?php if ($isWheel): ?>
<span class="status-pill success">Wheel geprüft</span>
<?php elseif ($release): ?>
<span class="status-pill warning">Kein installierbares Release</span>
<?php else: ?>
<span class="status-pill neutral">Kein installierbares Release</span>
<?php endif; ?>
</div>
<h3><a href="/plugins/<?= $e(rawurlencode($plugin['slug'])) ?>"><?= $e($plugin['name']) ?></a></h3>
<p><?= $e($plugin['summary'] ?: 'Für dieses Plugin ist noch keine Kurzbeschreibung hinterlegt.') ?></p>
<dl class="card-meta">
<div><dt>NetBox</dt><dd><?= $e($plugin['minNetboxVersion']) ?> <?= $e($plugin['maxNetboxVersion']) ?></dd></div>
<div><dt>Version</dt><dd><?= $release ? $e($release['version']) : '' ?></dd></div>
</dl>
<div class="card-footer">
<code><?= $e($plugin['packageName']) ?></code>
<a class="arrow-link" href="/plugins/<?= $e(rawurlencode($plugin['slug'])) ?>" aria-label="Details zu <?= $e($plugin['name']) ?>">Details <span aria-hidden="true">→</span></a>
</div>
</article>
<?php endforeach; ?>
</div>
<?php endif; ?>
<?php if (($pages ?? 1) > 1): ?>
<nav class="pagination" aria-label="Ergebnisseiten">
<?php $baseQuery = ['q' => $query ?? '', 'source' => $selectedSource ?? '', 'netbox_version' => $selectedNetboxVersion ?? '']; ?>
<?php if (($page ?? 1) > 1): ?><a href="/?<?= $e(http_build_query($baseQuery + ['page' => $page - 1])) ?>">← Zurück</a><?php endif; ?>
<span>Seite <?= $e($page) ?> von <?= $e($pages) ?></span>
<?php if (($page ?? 1) < $pages): ?><a href="/?<?= $e(http_build_query($baseQuery + ['page' => $page + 1])) ?>">Weiter →</a><?php endif; ?>
</nav>
<?php endif; ?>
</section>
<?php include __DIR__ . '/partials/footer.php'; ?>