←
APC-49
Created: 2026-01-20
•
Updated: 2026-01-20
Relationships
Loading...
Attachments
Loading...
Comments (4)
qa-agent
·
2026-01-20
## QA PASSED
See QA report document: 34a47b76-7890-4c2b-862b-73cfb3c0ffa0
### All Hypotheses Tested - All Passed
| Test | Result |
|------|--------|
| H1: Click triggers infinite re-render | PASS - State toggled without crash |
| H2: Multiple rapid clicks | PASS - No errors |
| H3: Save device with outlets | PASS - Device created successfully |
| H4: Edit mode loads existing outlets | PASS - Found 4 pre-checked outlets |
| H5: Conflict detection | PASS - 10 outlets marked 'in use' |
### Key Verification
The **infinite re-render loop bug is fixed**. Clicking outlet checkboxes now toggles selection cleanly without triggering the 'Maximum update depth exceeded' error.
### Features Working
- PDU Outlets collapsible section
- Single and multiple outlet selection
- Outlet state display (ON/OFF)
- Conflict detection ('in use' labels)
- Save behavior for new and existing devices
Fix verified working. Marking as done.
agent
·
2026-01-20
## Fix Applied: Infinite Re-render Loop
### Root Cause Analysis
The infinite re-render loop was caused by **event bubbling** when clicking the checkbox in the PDU Outlets grid.
**Problem:**
1. Each outlet item has a clickable parent `div` with an `onClick` handler that calls `handleToggleOutlet(outlet.id)`
2. Inside that div, there's a `Checkbox` component with an `onCheckedChange` handler that also calls `handleToggleOutlet(outlet.id)`
3. When clicking the checkbox:
- The checkbox's `onCheckedChange` fires first, toggling the outlet state
- The click event bubbles up to the parent div
- The div's `onClick` fires, toggling the outlet state again
4. This double-toggle causes state updates that trigger re-renders, which interact with React's reconciliation to cause the infinite loop
### Fix Applied
**File:** `frontend/src/components/device-form-dialog.tsx` (line 461)
Added `onClick={(e) => e.stopPropagation()}` to the Checkbox component to prevent the click event from bubbling up to the parent div.
Also added a code comment explaining why this is necessary for future maintainers.
### Verification
- `npm run build` - TypeScript compilation succeeds with no errors
- `npm test` - All 111 frontend tests pass
### Testing Instructions
1. Login to APC Controller
2. Navigate to Settings page
3. Click 'Add Device' button
4. Expand 'PDU Outlets' section
5. Click on any outlet - should toggle selection cleanly
6. Click on multiple outlets - all should select/deselect properly
7. Save device with outlets assigned - should save successfully
qa-agent
·
2026-01-20
## QA FAILED - CRITICAL BUG
See QA report document: 38c43535-3240-4a63-a76b-18d70cd0eba9
### Critical Bug Found
**Clicking any outlet triggers infinite React re-render loop**
**Steps to Reproduce:**
1. Login and navigate to Settings
2. Click 'Add Device'
3. Expand 'PDU Outlets' section
4. Click on any outlet
**Error:** `Maximum update depth exceeded`
**Location:** `device-form-dialog.tsx` line 298:7
### What Works
- Settings page loads
- Add Device dialog opens
- PDU Outlets section expands
- 24 outlets displayed with correct ON/OFF states
- Visual design looks good
### What's Broken
- Cannot select any outlets - clicking triggers infinite loop
- Feature is completely unusable
### Verdict
Returning to todo for fix. The outlet click handler has a bug causing infinite state updates.
### Screenshots saved to /tmp/
- APC-49-bug-02-expanded.png
- APC-49-bug-03-after-click.png
agent
·
2026-01-20
## Implementation Complete
### Changes Made
**Modified Files:**
1. `frontend/src/components/device-form-dialog.tsx` - Added PDU outlet selection UI
2. `frontend/src/app/settings/page.tsx` - Pass outlets and allDevices props to DeviceFormDialog
3. `frontend/src/components/ui/collapsible.tsx` - New component (shadcn/ui pattern)
4. `frontend/package.json` - Added @radix-ui/react-collapsible dependency
### Features Implemented
1. **Collapsible PDU Outlets Section**: A collapsible section in the DeviceFormDialog that expands to show all 24 PDU outlets in a compact grid (4-6 columns).
2. **Multiple Outlet Selection**: Users can select multiple outlets (1-24) for devices with dual/multiple PSUs using checkboxes.
3. **Outlet State Display**: Each outlet shows its current state (ON/OFF) via a badge.
4. **Conflict Prevention**: Outlets already assigned to OTHER devices are greyed out and disabled, with "in use" indicator showing they cannot be selected.
5. **Change Indicators**: Visual feedback shows pending changes:
- Green "+add" for outlets being added
- Red "-remove" for outlets being removed
- Badge showing counts "+X / -Y" in the section header
6. **Auto-expand**: The outlet section auto-expands when editing a device that already has outlets assigned.
7. **Save Behavior**:
- When editing: Updates device info AND outlet assignments (adds new, removes deselected)
- When creating: Creates device first, then assigns selected outlets
- Toast messages reflect outlet changes made
8. **Optional Props**: The new props (outlets, allDevices) are optional - the dialog fetches data itself if not provided, making it backwards compatible.
### Testing
- All 111 frontend tests pass
- TypeScript build succeeds with no errors
### Verification
The implementation can be verified by:
1. Opening the Settings page
2. Clicking "Add Device" or editing an existing device
3. Expanding the "PDU Outlets" collapsible section
4. Selecting/deselecting outlets
5. Saving and verifying the assignments are reflected in the device list