fix: keep approved devices in inventory after bulk approve
Bulk/single approve optimistically stripped approved rows from the local list, but scanApi.pending() still returns them (on-canvas, with an 'In N canvas' badge). The list went empty until the modal was reopened. Reload after approve instead of stripping, so approved rows stay visible with a fresh canvas_count. ha-relevant: yes
This commit is contained in:
@@ -287,8 +287,10 @@ export function PendingDevicesModal({ open, onClose, highlightId, initialStatus
|
||||
injectAutoEdges(res.data.edges)
|
||||
const extra = res.data.edges_created > 0 ? ` (+${res.data.edges_created} link${res.data.edges_created !== 1 ? 's' : ''})` : ''
|
||||
toast.success(`Approved ${nodeData.label}${extra}`)
|
||||
setDevices((prev) => prev.filter((d) => d.id !== device.id))
|
||||
// Keep the row (now on-canvas, shown with an "In N canvas" badge); reload
|
||||
// for a fresh canvas_count rather than dropping it until reopen.
|
||||
setSelected(null)
|
||||
await load()
|
||||
} catch {
|
||||
toast.error('Failed to approve device')
|
||||
}
|
||||
@@ -353,8 +355,11 @@ export function PendingDevicesModal({ open, onClose, highlightId, initialStatus
|
||||
})
|
||||
})
|
||||
injectAutoEdges(res.data.edges)
|
||||
setDevices((prev) => prev.filter((d) => !ids.includes(d.id)))
|
||||
// Don't strip approved rows locally: the inventory keeps them with an
|
||||
// "In N canvas" badge (that's what showOnCanvas toggles). Reload so they
|
||||
// reappear with a fresh canvas_count instead of vanishing until reopen.
|
||||
setSelectedIds(new Set())
|
||||
await load()
|
||||
const linkExtra = res.data.edges_created > 0 ? ` (+${res.data.edges_created} link${res.data.edges_created !== 1 ? 's' : ''})` : ''
|
||||
toast.success(`Approved ${res.data.approved} device${res.data.approved !== 1 ? 's' : ''}${linkExtra}`)
|
||||
} catch {
|
||||
|
||||
@@ -263,6 +263,27 @@ describe('PendingDevicesModal', () => {
|
||||
await waitFor(() => expect(mockBulkApprove).toHaveBeenCalledWith(['dev-a', 'dev-b'], null))
|
||||
})
|
||||
|
||||
it('keeps approved devices listed after bulk approve (reloads, not strips)', async () => {
|
||||
// After approve, pending() still returns the rows (now on-canvas w/ badge).
|
||||
mockPending
|
||||
.mockResolvedValueOnce({ data: [DEVICE_IP, DEVICE_ZIGBEE] })
|
||||
.mockResolvedValue({ data: [
|
||||
{ ...DEVICE_IP, canvas_count: 1 },
|
||||
{ ...DEVICE_ZIGBEE, canvas_count: 1 },
|
||||
] })
|
||||
render(<PendingDevicesModal {...baseProps} />)
|
||||
await waitFor(() => expect(screen.getByTestId('pending-card-dev-a')).toBeInTheDocument())
|
||||
fireEvent.click(screen.getByRole('button', { name: 'Select mode' }))
|
||||
fireEvent.click(screen.getByTestId('pending-card-dev-a'))
|
||||
fireEvent.click(screen.getByTestId('pending-card-dev-b'))
|
||||
fireEvent.click(screen.getByRole('button', { name: /Approve \(2\)/ }))
|
||||
await waitFor(() => expect(mockBulkApprove).toHaveBeenCalled())
|
||||
// Reloaded, so rows remain visible instead of the list going empty.
|
||||
await waitFor(() => expect(mockPending).toHaveBeenCalledTimes(2))
|
||||
expect(screen.getByTestId('pending-card-dev-a')).toBeInTheDocument()
|
||||
expect(screen.getByTestId('pending-card-dev-b')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('bulk approve carries the scanned MAC onto the canvas node (#168)', async () => {
|
||||
render(<PendingDevicesModal {...baseProps} />)
|
||||
await waitFor(() => expect(screen.getByTestId('pending-card-dev-a')).toBeInTheDocument())
|
||||
|
||||
Reference in New Issue
Block a user