fix: mount RollbackAlert, fix WifiPanel useEffect, remove unused PoolPanel prop
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -170,7 +170,6 @@ export function PoolPanel({ tenantId, deviceId, active }: ConfigPanelProps) {
|
|||||||
entries={typedEntries}
|
entries={typedEntries}
|
||||||
panel={panel}
|
panel={panel}
|
||||||
poolUsedBy={poolUsedBy}
|
poolUsedBy={poolUsedBy}
|
||||||
existingPools={typedEntries.map((e) => e.name).filter(Boolean)}
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* Change Preview Modal */}
|
{/* Change Preview Modal */}
|
||||||
@@ -197,13 +196,10 @@ function PoolTable({
|
|||||||
entries,
|
entries,
|
||||||
panel,
|
panel,
|
||||||
poolUsedBy,
|
poolUsedBy,
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
||||||
existingPools: _existingPools,
|
|
||||||
}: {
|
}: {
|
||||||
entries: PoolEntry[]
|
entries: PoolEntry[]
|
||||||
panel: PanelHook
|
panel: PanelHook
|
||||||
poolUsedBy: Record<string, string[]>
|
poolUsedBy: Record<string, string[]>
|
||||||
existingPools: string[]
|
|
||||||
}) {
|
}) {
|
||||||
const [dialogOpen, setDialogOpen] = useState(false)
|
const [dialogOpen, setDialogOpen] = useState(false)
|
||||||
const [editing, setEditing] = useState<PoolEntry | null>(null)
|
const [editing, setEditing] = useState<PoolEntry | null>(null)
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
* 2. Security Profiles (RouterOS 6 only) -- authentication, passphrases
|
* 2. Security Profiles (RouterOS 6 only) -- authentication, passphrases
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { useState, useMemo, useCallback } from 'react'
|
import { useState, useMemo, useCallback, useEffect } from 'react'
|
||||||
import {
|
import {
|
||||||
Wifi,
|
Wifi,
|
||||||
Plus,
|
Plus,
|
||||||
@@ -629,9 +629,7 @@ function WirelessEditDialog({
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Reset form when entry changes
|
// Reset form when entry changes
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
useEffect(() => {
|
||||||
const _entryId = entry?.['.id'] || ''
|
|
||||||
useState(() => {
|
|
||||||
if (entry) {
|
if (entry) {
|
||||||
setFormData({
|
setFormData({
|
||||||
ssid: entry.ssid || entry['configuration.ssid'] || '',
|
ssid: entry.ssid || entry['configuration.ssid'] || '',
|
||||||
@@ -643,7 +641,7 @@ function WirelessEditDialog({
|
|||||||
'security.passphrase': entry['security.passphrase'] || '',
|
'security.passphrase': entry['security.passphrase'] || '',
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
}, [entry])
|
||||||
|
|
||||||
// Use effect-like pattern to reset form on dialog open
|
// Use effect-like pattern to reset form on dialog open
|
||||||
const handleOpenChange = useCallback((nextOpen: boolean) => {
|
const handleOpenChange = useCallback((nextOpen: boolean) => {
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import {
|
|||||||
ShieldOff,
|
ShieldOff,
|
||||||
Shield,
|
Shield,
|
||||||
} from 'lucide-react'
|
} from 'lucide-react'
|
||||||
import { devicesApi, deviceGroupsApi, deviceTagsApi, tenantsApi, type DeviceResponse, type DeviceUpdate } from '@/lib/api'
|
import { devicesApi, deviceGroupsApi, deviceTagsApi, tenantsApi, configApi, type DeviceResponse, type DeviceUpdate } from '@/lib/api'
|
||||||
import { alertsApi } from '@/lib/alertsApi'
|
import { alertsApi } from '@/lib/alertsApi'
|
||||||
import { useAuth, canWrite, canDelete } from '@/lib/auth'
|
import { useAuth, canWrite, canDelete } from '@/lib/auth'
|
||||||
import { toast } from '@/components/ui/toast'
|
import { toast } from '@/components/ui/toast'
|
||||||
@@ -59,6 +59,7 @@ import { SimpleConfigView } from '@/components/simple-config/SimpleConfigView'
|
|||||||
import { WinBoxButton } from '@/components/fleet/WinBoxButton'
|
import { WinBoxButton } from '@/components/fleet/WinBoxButton'
|
||||||
import { RemoteWinBoxButton } from '@/components/fleet/RemoteWinBoxButton'
|
import { RemoteWinBoxButton } from '@/components/fleet/RemoteWinBoxButton'
|
||||||
import { SSHTerminal } from '@/components/fleet/SSHTerminal'
|
import { SSHTerminal } from '@/components/fleet/SSHTerminal'
|
||||||
|
import { RollbackAlert } from '@/components/config/RollbackAlert'
|
||||||
|
|
||||||
export const Route = createFileRoute(
|
export const Route = createFileRoute(
|
||||||
'/_authenticated/tenants/$tenantId/devices/$deviceId',
|
'/_authenticated/tenants/$tenantId/devices/$deviceId',
|
||||||
@@ -348,6 +349,21 @@ function DeviceDetailPage() {
|
|||||||
queryFn: () => tenantsApi.get(tenantId),
|
queryFn: () => tenantsApi.get(tenantId),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const { data: backups } = useQuery({
|
||||||
|
queryKey: ['config-backups', tenantId, deviceId],
|
||||||
|
queryFn: () => configApi.listBackups(tenantId, deviceId),
|
||||||
|
})
|
||||||
|
|
||||||
|
// True if a pre-restore backup was created within the last 30 minutes,
|
||||||
|
// indicating a config push just happened before the device went offline.
|
||||||
|
const hasRecentPushAlert = backups
|
||||||
|
? backups.some((b) => {
|
||||||
|
if (b.trigger_type !== 'pre-restore') return false
|
||||||
|
const age = Date.now() - new Date(b.created_at).getTime()
|
||||||
|
return age < 30 * 60 * 1000
|
||||||
|
})
|
||||||
|
: false
|
||||||
|
|
||||||
const { data: groups } = useQuery({
|
const { data: groups } = useQuery({
|
||||||
queryKey: ['device-groups', tenantId],
|
queryKey: ['device-groups', tenantId],
|
||||||
queryFn: () => deviceGroupsApi.list(tenantId),
|
queryFn: () => deviceGroupsApi.list(tenantId),
|
||||||
@@ -482,6 +498,14 @@ function DeviceDetailPage() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Emergency rollback banner */}
|
||||||
|
<RollbackAlert
|
||||||
|
tenantId={tenantId}
|
||||||
|
deviceId={deviceId}
|
||||||
|
deviceStatus={device.status}
|
||||||
|
hasRecentPushAlert={hasRecentPushAlert}
|
||||||
|
/>
|
||||||
|
|
||||||
{/* Config View (Simple or Standard) */}
|
{/* Config View (Simple or Standard) */}
|
||||||
<SimpleConfigView
|
<SimpleConfigView
|
||||||
tenantId={tenantId}
|
tenantId={tenantId}
|
||||||
|
|||||||
Reference in New Issue
Block a user