feat: improve dashboard and connection workflows
- add connection delete endpoint and update connection list handling - expand dashboard visualization behavior - update helpers/header and project TODO tracking
This commit is contained in:
41
app/modules/connections/delete.php
Normal file
41
app/modules/connections/delete.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
/**
|
||||
* app/modules/connections/delete.php
|
||||
*
|
||||
* Loescht eine Verbindung und leitet zur Liste zurueck.
|
||||
*/
|
||||
|
||||
$connectionId = (int)($_GET['id'] ?? $_POST['id'] ?? 0);
|
||||
|
||||
if ($connectionId <= 0) {
|
||||
$_SESSION['error'] = 'Ungueltige Verbindungs-ID';
|
||||
header('Location: ?module=connections&action=list');
|
||||
exit;
|
||||
}
|
||||
|
||||
$connection = $sql->single(
|
||||
"SELECT id FROM connections WHERE id = ?",
|
||||
"i",
|
||||
[$connectionId]
|
||||
);
|
||||
|
||||
if (!$connection) {
|
||||
$_SESSION['error'] = 'Verbindung nicht gefunden';
|
||||
header('Location: ?module=connections&action=list');
|
||||
exit;
|
||||
}
|
||||
|
||||
$rows = $sql->set(
|
||||
"DELETE FROM connections WHERE id = ?",
|
||||
"i",
|
||||
[$connectionId]
|
||||
);
|
||||
|
||||
if ($rows > 0) {
|
||||
$_SESSION['success'] = 'Verbindung geloescht';
|
||||
} else {
|
||||
$_SESSION['error'] = 'Verbindung konnte nicht geloescht werden';
|
||||
}
|
||||
|
||||
header('Location: ?module=connections&action=list');
|
||||
exit;
|
||||
@@ -2,19 +2,13 @@
|
||||
/**
|
||||
* app/modules/connections/list.php
|
||||
*
|
||||
* Übersicht der Netzwerkverbindungen
|
||||
* - Tabellarische Liste aller Verbindungen
|
||||
* - Filter nach Geräten, VLANs, Status
|
||||
* - Später: Visuelle Netzwerk-Topologie
|
||||
* Uebersicht der Netzwerkverbindungen
|
||||
*/
|
||||
|
||||
// =========================
|
||||
// Filter einlesen
|
||||
// =========================
|
||||
$search = trim($_GET['search'] ?? '');
|
||||
$deviceId = (int)($_GET['device_id'] ?? 0);
|
||||
$selectedConnectionId = (int)($_GET['connection_id'] ?? 0);
|
||||
|
||||
// Einheitliche Endpunkt-Aufloesung fuer polymorphe Port-Typen.
|
||||
$endpointUnionSql = "
|
||||
SELECT
|
||||
'device' AS endpoint_type,
|
||||
@@ -60,16 +54,13 @@ $endpointUnionSql = "
|
||||
LEFT JOIN floors f ON f.id = fp.floor_id
|
||||
";
|
||||
|
||||
// =========================
|
||||
// WHERE-Clause bauen
|
||||
// =========================
|
||||
$where = [];
|
||||
$types = '';
|
||||
$params = [];
|
||||
|
||||
if ($search !== '') {
|
||||
$where[] = "(e1.owner_name LIKE ? OR e2.owner_name LIKE ? OR e1.port_name LIKE ? OR e2.port_name LIKE ?)";
|
||||
$types .= "ssss";
|
||||
$types .= 'ssss';
|
||||
$params[] = "%$search%";
|
||||
$params[] = "%$search%";
|
||||
$params[] = "%$search%";
|
||||
@@ -78,16 +69,13 @@ if ($search !== '') {
|
||||
|
||||
if ($deviceId > 0) {
|
||||
$where[] = "(e1.owner_device_id = ? OR e2.owner_device_id = ?)";
|
||||
$types .= "ii";
|
||||
$types .= 'ii';
|
||||
$params[] = $deviceId;
|
||||
$params[] = $deviceId;
|
||||
}
|
||||
|
||||
$whereSql = $where ? "WHERE " . implode(" AND ", $where) : "";
|
||||
$whereSql = $where ? 'WHERE ' . implode(' AND ', $where) : '';
|
||||
|
||||
// =========================
|
||||
// Verbindungen laden
|
||||
// =========================
|
||||
$connections = $sql->get(
|
||||
"SELECT
|
||||
c.id,
|
||||
@@ -125,10 +113,22 @@ $connections = $sql->get(
|
||||
$params
|
||||
);
|
||||
|
||||
// =========================
|
||||
// Filter-Daten
|
||||
// =========================
|
||||
$devices = $sql->get("SELECT id, name FROM devices ORDER BY name", "", []);
|
||||
$devices = $sql->get('SELECT id, name FROM devices ORDER BY name', '', []);
|
||||
|
||||
$selectedConnection = null;
|
||||
if ($selectedConnectionId > 0) {
|
||||
foreach ((array)$connections as $entry) {
|
||||
if ((int)($entry['id'] ?? 0) === $selectedConnectionId) {
|
||||
$selectedConnection = $entry;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($selectedConnection === null && !empty($connections)) {
|
||||
$selectedConnection = $connections[0];
|
||||
$selectedConnectionId = (int)($selectedConnection['id'] ?? 0);
|
||||
}
|
||||
|
||||
$selectedDevice = null;
|
||||
$selectedDevicePorts = [];
|
||||
@@ -140,7 +140,7 @@ if ($deviceId > 0) {
|
||||
FROM devices d
|
||||
LEFT JOIN device_types dt ON d.device_type_id = dt.id
|
||||
WHERE d.id = ?",
|
||||
"i",
|
||||
'i',
|
||||
[$deviceId]
|
||||
);
|
||||
|
||||
@@ -159,7 +159,7 @@ if ($deviceId > 0) {
|
||||
JOIN device_ports dp ON dp.id = dpm.device_port_id
|
||||
WHERE dp.device_id = ?
|
||||
) p",
|
||||
"ii",
|
||||
'ii',
|
||||
[$deviceId, $deviceId]
|
||||
)['cnt'] ?? 0);
|
||||
|
||||
@@ -187,7 +187,7 @@ if ($deviceId > 0) {
|
||||
OR (c.port_b_type = 'patchpanel' AND e2.endpoint_type = 'floor_patchpanel')
|
||||
)
|
||||
WHERE e1.owner_device_id = ? OR e2.owner_device_id = ?",
|
||||
"ii",
|
||||
'ii',
|
||||
[$deviceId, $deviceId]
|
||||
)['cnt'] ?? 0);
|
||||
|
||||
@@ -207,7 +207,7 @@ if ($deviceId > 0) {
|
||||
) p
|
||||
ORDER BY sort_id
|
||||
LIMIT 12",
|
||||
"ii",
|
||||
'ii',
|
||||
[$deviceId, $deviceId]
|
||||
);
|
||||
|
||||
@@ -230,159 +230,247 @@ if ($deviceId > 0) {
|
||||
}
|
||||
}
|
||||
|
||||
$buildListUrl = static function (array $extra = []) use ($search, $deviceId): string {
|
||||
$query = ['module' => 'connections', 'action' => 'list'];
|
||||
if ($search !== '') {
|
||||
$query['search'] = $search;
|
||||
}
|
||||
if ($deviceId > 0) {
|
||||
$query['device_id'] = $deviceId;
|
||||
}
|
||||
foreach ($extra as $key => $value) {
|
||||
if ($value === null || $value === '') {
|
||||
continue;
|
||||
}
|
||||
$query[$key] = $value;
|
||||
}
|
||||
return '?' . http_build_query($query);
|
||||
};
|
||||
?>
|
||||
|
||||
<div class="connections-container">
|
||||
<h1>Netzwerkverbindungen</h1>
|
||||
<div class="connections-layout">
|
||||
<div class="connections-container">
|
||||
<h1>Netzwerkverbindungen</h1>
|
||||
|
||||
<!-- =========================
|
||||
Filter-Toolbar
|
||||
========================= -->
|
||||
<div class="filter-form">
|
||||
<form method="GET">
|
||||
<input type="hidden" name="module" value="connections">
|
||||
<input type="hidden" name="action" value="list">
|
||||
<div class="filter-form">
|
||||
<form method="GET">
|
||||
<input type="hidden" name="module" value="connections">
|
||||
<input type="hidden" name="action" value="list">
|
||||
|
||||
<input type="text" name="search" placeholder="Suche nach Gerät oder Port…"
|
||||
value="<?php echo htmlspecialchars($search); ?>" class="search-input">
|
||||
<input type="text" name="search" placeholder="Suche nach Geraet oder Port..."
|
||||
value="<?php echo htmlspecialchars($search); ?>" class="search-input">
|
||||
|
||||
<select name="device_id">
|
||||
<option value="">- Alle Geräte -</option>
|
||||
<?php foreach ($devices as $device): ?>
|
||||
<option value="<?php echo $device['id']; ?>"
|
||||
<?php echo $device['id'] === $deviceId ? 'selected' : ''; ?>>
|
||||
<?php echo htmlspecialchars($device['name']); ?>
|
||||
</option>
|
||||
<select name="device_id">
|
||||
<option value="">- Alle Geraete -</option>
|
||||
<?php foreach ($devices as $device): ?>
|
||||
<option value="<?php echo (int)$device['id']; ?>"
|
||||
<?php echo ((int)$device['id'] === $deviceId) ? 'selected' : ''; ?>>
|
||||
<?php echo htmlspecialchars((string)$device['name']); ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
|
||||
<button type="submit" class="button">Filter</button>
|
||||
<a href="?module=connections&action=list" class="button">Reset</a>
|
||||
<a href="?module=connections&action=edit" class="button button-primary">+ Neue Verbindung</a>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<?php if (!empty($connections)): ?>
|
||||
<table class="connections-list">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Von (Geraet -> Port)</th>
|
||||
<th>Nach (Geraet -> Port)</th>
|
||||
<th>VLANs</th>
|
||||
<th>Beschreibung</th>
|
||||
<th>Status</th>
|
||||
<th>Aktionen</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($connections as $conn): ?>
|
||||
<?php
|
||||
$connId = (int)($conn['id'] ?? 0);
|
||||
$comment = trim((string)($conn['comment'] ?? ''));
|
||||
$hasMissingInfo = empty($conn['endpoint_a_name']) || empty($conn['endpoint_b_name'])
|
||||
|| empty($conn['port_a_name']) || empty($conn['port_b_name']);
|
||||
$commentLower = mb_strtolower($comment, 'UTF-8');
|
||||
$warningFromComment = preg_match('/warn|achtung|critical/', $commentLower) === 1;
|
||||
$hasWarning = $hasMissingInfo || $warningFromComment;
|
||||
$rowClass = $connId === $selectedConnectionId ? 'connection-row-selected' : '';
|
||||
$vlanList = [];
|
||||
if (!empty($conn['vlan_config'])) {
|
||||
$vlanList = (array)json_decode((string)$conn['vlan_config'], true);
|
||||
}
|
||||
?>
|
||||
<tr class="<?php echo $rowClass; ?>">
|
||||
<td>
|
||||
<strong><?php echo htmlspecialchars((string)($conn['endpoint_a_name'] ?? 'N/A')); ?></strong><br>
|
||||
<small><?php echo htmlspecialchars((string)($conn['port_a_name'] ?? '-')); ?></small>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<strong><?php echo htmlspecialchars((string)($conn['endpoint_b_name'] ?? 'N/A')); ?></strong><br>
|
||||
<small><?php echo htmlspecialchars((string)($conn['port_b_name'] ?? '-')); ?></small>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<small><?php echo !empty($vlanList) ? htmlspecialchars(implode(', ', $vlanList)) : '-'; ?></small>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<small><?php echo htmlspecialchars($comment); ?></small>
|
||||
</td>
|
||||
|
||||
<td class="status-cell">
|
||||
<?php if ($hasWarning): ?>
|
||||
<span class="status-badge status-badge-warning" title="Unvollstaendige oder kritische Verbindung">Warnung</span>
|
||||
<?php else: ?>
|
||||
<span class="status-badge status-badge-ok" title="Verbindung vollstaendig">OK</span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
|
||||
<td class="actions">
|
||||
<a href="<?php echo htmlspecialchars($buildListUrl(['connection_id' => $connId])); ?>" class="button button-small">Details</a>
|
||||
<a href="?module=connections&action=edit&id=<?php echo $connId; ?>" class="button button-small">Bearbeiten</a>
|
||||
<a href="?module=connections&action=swap&id=<?php echo $connId; ?>" class="button button-small" onclick="return confirm('Von/Nach fuer diese Verbindung vertauschen?');">Von/Nach tauschen</a>
|
||||
<a href="?module=connections&action=delete&id=<?php echo $connId; ?>" class="button button-small button-danger"
|
||||
data-confirm-delete="true"
|
||||
data-confirm-message="Diese Verbindung wirklich loeschen?">
|
||||
Loeschen
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
|
||||
<button type="submit" class="button">Filter</button>
|
||||
<a href="?module=connections&action=list" class="button">Reset</a>
|
||||
<a href="?module=connections&action=edit" class="button button-primary">+ Neue Verbindung</a>
|
||||
</form>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php else: ?>
|
||||
<div class="empty-state">
|
||||
<p>Keine Verbindungen gefunden.</p>
|
||||
<p>
|
||||
<a href="?module=connections&action=edit" class="button button-primary">
|
||||
Erste Verbindung anlegen
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<!-- =========================
|
||||
Verbindungs-Tabelle
|
||||
========================= -->
|
||||
<?php if (!empty($connections)): ?>
|
||||
<table class="connections-list">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Von (Gerät → Port)</th>
|
||||
<th>Nach (Gerät → Port)</th>
|
||||
<th>VLANs</th>
|
||||
<th>Beschreibung</th>
|
||||
<th>Status</th>
|
||||
<th>Aktionen</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($connections as $conn): ?>
|
||||
<?php
|
||||
$comment = trim($conn['comment'] ?? '');
|
||||
$hasMissingInfo = empty($conn['endpoint_a_name']) || empty($conn['endpoint_b_name'])
|
||||
|| empty($conn['port_a_name']) || empty($conn['port_b_name']);
|
||||
$commentLower = mb_strtolower($comment, 'UTF-8');
|
||||
$warningFromComment = preg_match('/warn|achtung|critical/', $commentLower);
|
||||
$hasWarning = $hasMissingInfo || $warningFromComment;
|
||||
?>
|
||||
<tr>
|
||||
<td>
|
||||
<strong><?php echo htmlspecialchars($conn['endpoint_a_name'] ?? 'N/A'); ?></strong><br>
|
||||
<small><?php echo htmlspecialchars($conn['port_a_name'] ?? '—'); ?></small>
|
||||
</td>
|
||||
<aside class="connections-sidebar">
|
||||
<section class="sidebar-card">
|
||||
<h3>Ausgewaehlte Verbindung</h3>
|
||||
<?php if ($selectedConnection): ?>
|
||||
<?php
|
||||
$selectedConnId = (int)($selectedConnection['id'] ?? 0);
|
||||
$selectedVlans = [];
|
||||
if (!empty($selectedConnection['vlan_config'])) {
|
||||
$selectedVlans = (array)json_decode((string)$selectedConnection['vlan_config'], true);
|
||||
}
|
||||
?>
|
||||
<p><strong>ID:</strong> #<?php echo $selectedConnId; ?></p>
|
||||
<p><strong>Von:</strong><br>
|
||||
<?php echo htmlspecialchars((string)($selectedConnection['endpoint_a_name'] ?? 'N/A')); ?><br>
|
||||
<small><?php echo htmlspecialchars((string)($selectedConnection['port_a_name'] ?? '-')); ?></small>
|
||||
</p>
|
||||
<p><strong>Nach:</strong><br>
|
||||
<?php echo htmlspecialchars((string)($selectedConnection['endpoint_b_name'] ?? 'N/A')); ?><br>
|
||||
<small><?php echo htmlspecialchars((string)($selectedConnection['port_b_name'] ?? '-')); ?></small>
|
||||
</p>
|
||||
<p><strong>VLANs:</strong> <?php echo !empty($selectedVlans) ? htmlspecialchars(implode(', ', $selectedVlans)) : '-'; ?></p>
|
||||
<p><strong>Kommentar:</strong> <?php echo htmlspecialchars((string)($selectedConnection['comment'] ?? '-')); ?></p>
|
||||
<div class="sidebar-actions">
|
||||
<a href="?module=connections&action=edit&id=<?php echo $selectedConnId; ?>" class="button button-small">Bearbeiten</a>
|
||||
<a href="?module=connections&action=swap&id=<?php echo $selectedConnId; ?>" class="button button-small" onclick="return confirm('Von/Nach fuer diese Verbindung vertauschen?');">Tauschen</a>
|
||||
<a href="?module=connections&action=delete&id=<?php echo $selectedConnId; ?>" class="button button-small button-danger" data-confirm-delete="true" data-confirm-message="Diese Verbindung wirklich loeschen?">Loeschen</a>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<p><em>Keine Verbindung ausgewaehlt.</em></p>
|
||||
<?php endif; ?>
|
||||
</section>
|
||||
|
||||
<td>
|
||||
<strong><?php echo htmlspecialchars($conn['endpoint_b_name'] ?? 'N/A'); ?></strong><br>
|
||||
<small><?php echo htmlspecialchars($conn['port_b_name'] ?? '—'); ?></small>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<small>
|
||||
<?php
|
||||
if ($conn['vlan_config']) {
|
||||
$vlan = json_decode($conn['vlan_config'], true);
|
||||
echo htmlspecialchars(implode(', ', (array)$vlan));
|
||||
} else {
|
||||
echo '—';
|
||||
}
|
||||
?>
|
||||
</small>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<small><?php echo htmlspecialchars($conn['comment'] ?? ''); ?></small>
|
||||
</td>
|
||||
<td class="status-cell">
|
||||
<?php if ($hasWarning): ?>
|
||||
<span class="status-badge status-badge-warning" title="Unvollständige oder kritische Verbindung">
|
||||
⚠️ Warnung
|
||||
</span>
|
||||
<section class="sidebar-card">
|
||||
<?php if ($selectedDevice): ?>
|
||||
<h3>Ausgewaehltes Geraet</h3>
|
||||
<p><strong><?php echo htmlspecialchars((string)$selectedDevice['name']); ?></strong></p>
|
||||
<p>Typ: <?php echo htmlspecialchars((string)($selectedDevice['type_name'] ?? '-')); ?></p>
|
||||
<p>Ports: <?php echo (int)$selectedDevice['port_count']; ?></p>
|
||||
<p>Verbindungen: <?php echo (int)$selectedDevice['connection_count']; ?></p>
|
||||
<p>
|
||||
VLANs:
|
||||
<?php if (!empty($selectedDeviceVlans)): ?>
|
||||
<?php echo htmlspecialchars(implode(', ', $selectedDeviceVlans)); ?>
|
||||
<?php else: ?>
|
||||
<span class="status-badge status-badge-ok" title="Verbindung vollständig">
|
||||
✔️ OK
|
||||
</span>
|
||||
-
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
|
||||
<td class="actions">
|
||||
<a href="?module=connections&action=edit&id=<?php echo $conn['id']; ?>" class="button button-small">Bearbeiten</a>
|
||||
<a href="?module=connections&action=swap&id=<?php echo $conn['id']; ?>" class="button button-small" onclick="return confirm('Von/Nach fuer diese Verbindung vertauschen?');">Von/Nach tauschen</a>
|
||||
<a href="#" class="button button-small button-danger"
|
||||
data-confirm-delete="true"
|
||||
data-confirm-message="Diese Verbindung wirklich löschen?"
|
||||
data-confirm-feedback="Löschen noch nicht implementiert">
|
||||
Löschen
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<?php else: ?>
|
||||
<div class="empty-state">
|
||||
<p>Keine Verbindungen gefunden.</p>
|
||||
<p>
|
||||
<a href="?module=connections&action=edit" class="button button-primary">
|
||||
Erste Verbindung anlegen
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</p>
|
||||
<?php if (!empty($selectedDevicePorts)): ?>
|
||||
<h4>Ports (max. 12)</h4>
|
||||
<ul>
|
||||
<?php foreach ($selectedDevicePorts as $port): ?>
|
||||
<li><?php echo htmlspecialchars((string)$port['name']); ?></li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
<?php endif; ?>
|
||||
<?php else: ?>
|
||||
<h3>Ausgewaehltes Geraet</h3>
|
||||
<p><em>Bitte ein Geraet im Filter auswaehlen.</em></p>
|
||||
<?php endif; ?>
|
||||
</section>
|
||||
</aside>
|
||||
</div>
|
||||
|
||||
<!-- =========================
|
||||
Sidebar / Details
|
||||
========================= -->
|
||||
<style>
|
||||
.connections-layout {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr) 320px;
|
||||
gap: 20px;
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
<aside class="sidebar">
|
||||
<?php if ($selectedDevice): ?>
|
||||
<h3>Ausgewähltes Gerät</h3>
|
||||
<p><strong><?php echo htmlspecialchars($selectedDevice['name']); ?></strong></p>
|
||||
<p>Typ: <?php echo htmlspecialchars($selectedDevice['type_name'] ?? '—'); ?></p>
|
||||
<p>Ports: <?php echo (int)$selectedDevice['port_count']; ?></p>
|
||||
<p>Verbindungen: <?php echo (int)$selectedDevice['connection_count']; ?></p>
|
||||
<p>
|
||||
VLANs:
|
||||
<?php if (!empty($selectedDeviceVlans)): ?>
|
||||
<?php echo htmlspecialchars(implode(', ', $selectedDeviceVlans)); ?>
|
||||
<?php else: ?>
|
||||
—
|
||||
<?php endif; ?>
|
||||
</p>
|
||||
<?php if (!empty($selectedDevicePorts)): ?>
|
||||
<h4>Ports (max. 12)</h4>
|
||||
<ul>
|
||||
<?php foreach ($selectedDevicePorts as $port): ?>
|
||||
<li><?php echo htmlspecialchars($port['name']); ?></li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
<?php endif; ?>
|
||||
<?php else: ?>
|
||||
<p><em>Bitte ein Gerät im Filter auswählen.</em></p>
|
||||
<?php endif; ?>
|
||||
.connections-sidebar {
|
||||
position: sticky;
|
||||
top: 92px;
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
<!-- TODO: Verbindung bearbeiten / löschen -->
|
||||
</aside>
|
||||
.sidebar-card {
|
||||
background: #fff;
|
||||
border: 1px solid #e0e6ef;
|
||||
border-radius: 12px;
|
||||
padding: 14px;
|
||||
box-shadow: 0 8px 24px rgba(15, 26, 45, 0.08);
|
||||
}
|
||||
|
||||
.sidebar-card h3,
|
||||
.sidebar-card h4 {
|
||||
margin: 0 0 10px;
|
||||
}
|
||||
|
||||
.sidebar-card p {
|
||||
margin: 0 0 8px;
|
||||
}
|
||||
|
||||
.sidebar-actions {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.connection-row-selected {
|
||||
background: #edf5ff;
|
||||
}
|
||||
|
||||
@media (max-width: 1100px) {
|
||||
.connections-layout {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.connections-sidebar {
|
||||
position: static;
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user