@@ -1,4 +1,5 @@
|
|||||||
import { useCallback, useEffect, useState, type ReactNode } from 'react'
|
import { useCallback, useEffect, useState, type ReactNode } from 'react'
|
||||||
|
import { Link } from 'react-router-dom'
|
||||||
import { Loader2, Pencil, Plus, RefreshCw, Trash2 } from 'lucide-react'
|
import { Loader2, Pencil, Plus, RefreshCw, Trash2 } from 'lucide-react'
|
||||||
import { toast } from 'sonner'
|
import { toast } from 'sonner'
|
||||||
import { api, ApiError, type Client, type ClientStatus, type Vlan } from '@/lib/api'
|
import { api, ApiError, type Client, type ClientStatus, type Vlan } from '@/lib/api'
|
||||||
@@ -53,6 +54,9 @@ export function Clients() {
|
|||||||
const [pageSize, setPageSize] = usePageSize()
|
const [pageSize, setPageSize] = usePageSize()
|
||||||
const [page, setPage] = useState(1)
|
const [page, setPage] = useState(1)
|
||||||
const pageCount = Math.max(1, Math.ceil(total / pageSize))
|
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.
|
// Server-side pagination: fetch only the current page's rows.
|
||||||
const load = useCallback(async () => {
|
const load = useCallback(async () => {
|
||||||
@@ -96,12 +100,23 @@ export function Clients() {
|
|||||||
<RefreshCw className={loading ? 'animate-spin' : ''} />
|
<RefreshCw className={loading ? 'animate-spin' : ''} />
|
||||||
</Button>
|
</Button>
|
||||||
<ClientImportExport onImported={load} />
|
<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
|
<Plus /> Add device
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</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">
|
<div className="rounded-lg border bg-background">
|
||||||
<Table>
|
<Table>
|
||||||
<TableHeader>
|
<TableHeader>
|
||||||
|
|||||||
Reference in New Issue
Block a user