Dashboard-Zahlen (Kategorien, Read Later), Host/IP getrennte Spalten bei Diensten, Scanner-Uebersicht beim Massen-Scan

This commit is contained in:
2026-07-20 17:51:58 +02:00
parent 0580d46000
commit 724f076c8c
3 changed files with 111 additions and 18 deletions

View File

@@ -103,7 +103,7 @@ function CategorySelect({
);
}
const EDIT_FORM_COLSPAN = 11;
const EDIT_FORM_COLSPAN = 12;
function EditForm({ service, onDone }: { service: Service; onDone: () => void }) {
const queryClient = useQueryClient();
@@ -239,6 +239,7 @@ function EditForm({ service, onDone }: { service: Service; onDone: () => void })
function ServiceRow({
service,
deviceMac,
deviceIp,
draggable,
onDragStart,
onDragOver,
@@ -247,6 +248,7 @@ function ServiceRow({
}: {
service: Service;
deviceMac: string | null;
deviceIp: string | null;
draggable: boolean;
onDragStart: (e: DragEvent<HTMLTableRowElement>) => void;
onDragOver: (e: DragEvent<HTMLTableRowElement>) => void;
@@ -328,6 +330,9 @@ function ServiceRow({
<td className="px-4 py-3 font-mono text-xs text-black/60 dark:text-white/60">
{service.hostname}
</td>
<td className="px-4 py-3 font-mono text-xs text-black/60 dark:text-white/60">
{deviceIp ?? ""}
</td>
<td className="px-4 py-3 text-black/60 dark:text-white/60">{service.category ?? ""}</td>
<td className="px-4 py-3 font-mono text-xs text-black/40 dark:text-white/40">
{deviceMac ?? ""}
@@ -371,7 +376,7 @@ function ServiceRow({
);
}
type SortColumn = "displayName" | "hostname" | "category" | "alias" | "port" | "https" | null;
type SortColumn = "displayName" | "hostname" | "ip" | "category" | "alias" | "port" | "https" | null;
function SortableHeader({
label,
@@ -417,6 +422,12 @@ export function ServicesPage() {
return map;
}, [devices]);
const ipByDeviceId = useMemo(() => {
const map: Record<string, string | null> = {};
for (const d of devices ?? []) map[d.id] = d.ip;
return map;
}, [devices]);
const reorderMutation = useMutation({
mutationFn: reorderServicesRequest,
onSuccess: () => {
@@ -440,6 +451,13 @@ export function ServicesPage() {
case "hostname":
cmp = a.hostname.localeCompare(b.hostname);
break;
case "ip":
cmp = (ipByDeviceId[a.deviceId] ?? "").localeCompare(
ipByDeviceId[b.deviceId] ?? "",
undefined,
{ numeric: true }
);
break;
case "category":
cmp = (a.category ?? "").localeCompare(b.category ?? "");
break;
@@ -456,7 +474,7 @@ export function ServicesPage() {
return sortDirection === "asc" ? cmp : -cmp;
});
return sorted;
}, [baseList, sortColumn, sortDirection]);
}, [baseList, sortColumn, sortDirection, ipByDeviceId]);
function handleHeaderClick(column: SortColumn) {
if (sortColumn === column) {
@@ -526,14 +544,15 @@ export function ServicesPage() {
) : list.length > 0 ? (
<div className="overflow-hidden rounded-2xl border border-black/10 dark:border-white/10">
<div className="overflow-x-auto">
<table className="w-full min-w-[1020px] text-sm">
<table className="w-full min-w-[1140px] text-sm">
<thead>
<tr className="border-b border-black/10 bg-black/[0.02] text-left text-xs
uppercase tracking-wide text-black/40 dark:border-white/10 dark:bg-white/5 dark:text-white/40">
<th className="px-2 py-2" />
<th className="px-2 py-2" />
<SortableHeader label="Dienst" column="displayName" activeColumn={sortColumn} direction={sortDirection} onClick={handleHeaderClick} />
<SortableHeader label="Host/IP" column="hostname" activeColumn={sortColumn} direction={sortDirection} onClick={handleHeaderClick} />
<SortableHeader label="Host" column="hostname" activeColumn={sortColumn} direction={sortDirection} onClick={handleHeaderClick} />
<SortableHeader label="IP" column="ip" activeColumn={sortColumn} direction={sortDirection} onClick={handleHeaderClick} />
<SortableHeader label="Kategorie" column="category" activeColumn={sortColumn} direction={sortDirection} onClick={handleHeaderClick} />
<th className="px-4 py-2 font-medium">MAC</th>
<SortableHeader label="Alias" column="alias" activeColumn={sortColumn} direction={sortDirection} onClick={handleHeaderClick} />
@@ -549,6 +568,7 @@ export function ServicesPage() {
key={service.id}
service={service}
deviceMac={macByDeviceId[service.deviceId] ?? null}
deviceIp={ipByDeviceId[service.deviceId] ?? null}
draggable={dragEnabled}
isDragging={draggedId === service.id}
onDragStart={handleDragStart(service.id)}