@@ -1,4 +1,5 @@
|
||||
import { useCallback, useEffect, useState, type ReactNode } from 'react'
|
||||
import { Link } from 'react-router-dom'
|
||||
import { Loader2, Pencil, Plus, RefreshCw, Trash2 } from 'lucide-react'
|
||||
import { toast } from 'sonner'
|
||||
import { api, ApiError, type Client, type ClientStatus, type Vlan } from '@/lib/api'
|
||||
@@ -53,6 +54,9 @@ export function Clients() {
|
||||
const [pageSize, setPageSize] = usePageSize()
|
||||
const [page, setPage] = useState(1)
|
||||
const pageCount = Math.max(1, Math.ceil(total / pageSize))
|
||||
// A device must be assigned to a VLAN group, so adding one is impossible
|
||||
// until at least one VLAN exists.
|
||||
const noVlans = !loading && vlans.length === 0
|
||||
|
||||
// Server-side pagination: fetch only the current page's rows.
|
||||
const load = useCallback(async () => {
|
||||
@@ -96,12 +100,23 @@ export function Clients() {
|
||||
<RefreshCw className={loading ? 'animate-spin' : ''} />
|
||||
</Button>
|
||||
<ClientImportExport onImported={load} />
|
||||
<Button onClick={() => setAddOpen(true)}>
|
||||
<Button
|
||||
onClick={() => setAddOpen(true)}
|
||||
disabled={noVlans}
|
||||
title={noVlans ? 'Add a VLAN before registering a device' : undefined}
|
||||
>
|
||||
<Plus /> Add device
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{noVlans && (
|
||||
<div className="rounded-lg border border-amber-500/40 bg-amber-500/10 px-4 py-3 text-sm text-amber-700 dark:text-amber-400">
|
||||
No VLANs exist yet. <Link to="/vlans" className="font-medium underline">Add a VLAN</Link>{' '}
|
||||
before registering a device.
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="rounded-lg border bg-background">
|
||||
<Table>
|
||||
<TableHeader>
|
||||
|
||||
Reference in New Issue
Block a user