Files
Charon/docs/plans/archive/comprehensive_modal_fix_spec.md
akanealw eec8c28fb3
Some checks are pending
Go Benchmark / Performance Regression Check (push) Waiting to run
Cerberus Integration / Cerberus Security Stack Integration (push) Waiting to run
Upload Coverage to Codecov / Backend Codecov Upload (push) Waiting to run
Upload Coverage to Codecov / Frontend Codecov Upload (push) Waiting to run
CodeQL - Analyze / CodeQL analysis (go) (push) Waiting to run
CodeQL - Analyze / CodeQL analysis (javascript-typescript) (push) Waiting to run
CrowdSec Integration / CrowdSec Bouncer Integration (push) Waiting to run
Docker Build, Publish & Test / build-and-push (push) Waiting to run
Docker Build, Publish & Test / Security Scan PR Image (push) Blocked by required conditions
Quality Checks / Auth Route Protection Contract (push) Waiting to run
Quality Checks / Codecov Trigger/Comment Parity Guard (push) Waiting to run
Quality Checks / Backend (Go) (push) Waiting to run
Quality Checks / Frontend (React) (push) Waiting to run
Rate Limit integration / Rate Limiting Integration (push) Waiting to run
Security Scan (PR) / Trivy Binary Scan (push) Waiting to run
Supply Chain Verification (PR) / Verify Supply Chain (push) Waiting to run
WAF integration / Coraza WAF Integration (push) Waiting to run
changed perms
2026-04-22 18:19:14 +00:00

207 lines
7.4 KiB
Markdown
Executable File

# Comprehensive Modal Z-Index Fix Plan
**Date**: 2026-02-04
**Issue**: Widespread modal overlay z-index pattern breaking dropdown interactions
**Scope**: 11 modal components across the application
**Fix Strategy**: Unified 3-layer modal restructuring
---
## Executive Summary
Multiple modal components throughout the application use the same problematic pattern:
```tsx
<div className="fixed inset-0 bg-black/50 ... z-50">
{/* Form with dropdowns inside */}
</div>
```
This pattern creates a z-index stacking context that blocks native HTML `<select>` dropdown menus from rendering properly, making them unclickable.
---
## Affected Components by Priority
### P0 - CRITICAL: Modals with SELECT Dropdowns (Completely Broken)
| Component | File | Line | Dropdowns | Impact |
|-----------|------|------|-----------|--------|
| **ProxyHostForm** | `frontend/src/components/ProxyHostForm.tsx` | 514 | ACL selector, Security Headers | **CRITICAL**: Users cannot assign security policies |
| **EditMonitorModal** | `frontend/src/pages/Uptime.tsx` | 230 | Monitor type (HTTP/TCP) | **HIGH**: Users cannot edit monitor configuration |
| **CreateMonitorModal** | `frontend/src/pages/Uptime.tsx` | 339 | Monitor type (HTTP/TCP) | **HIGH**: Users cannot create new monitors |
| **InviteUserModal** | `frontend/src/pages/UsersPage.tsx` | 171 | Role, Permission mode | **HIGH**: Admin cannot invite users with roles |
| **EditPermissionsModal** | `frontend/src/pages/UsersPage.tsx` | 434 | Permission mode, Allowed/Blocked hosts | **HIGH**: Admin cannot modify user permissions |
| **BanIPModal** | `frontend/src/pages/CrowdSecConfig.tsx` | 1175 | Ban duration | **MEDIUM**: Admin cannot set custom ban durations |
| **RemoteServerForm** | `frontend/src/components/RemoteServerForm.tsx` | 69 | Provider (Generic/Docker/K8s) | **MEDIUM**: Users cannot add remote servers |
### P1 - HIGH: Modals with Other Interactive Elements
| Component | File | Line | Elements | Impact |
|-----------|------|------|----------|--------|
| **PasswordPromptModal** | `frontend/src/pages/Account.tsx` | 473 | Password input, buttons | **LOW**: Simple inputs work |
| **EmailConfirmModal** | `frontend/src/pages/Account.tsx` | 523 | Buttons only | **NONE**: No form inputs |
### P2 - MEDIUM: Modal Pattern Analysis Required
| Component | File | Line | Status | Impact |
|-----------|------|------|--------|--------|
| **ConfirmDialog** | `frontend/src/pages/WafConfig.tsx` | 72 | Buttons only | **NONE**: No form inputs |
| **SecurityNotificationModal** | `frontend/src/components/SecurityNotificationSettingsModal.tsx` | 58 | **TBD** - Need analysis | **UNKNOWN** |
| **ImportSitesModal** | `frontend/src/components/ImportSitesModal.tsx` | 75 | **TBD** - Need analysis | **UNKNOWN** |
| **CertificateCleanupDialog** | `frontend/src/components/dialogs/CertificateCleanupDialog.tsx` | 27 | Buttons only | **NONE**: No form inputs |
| **ImportSuccessModal** | `frontend/src/components/dialogs/ImportSuccessModal.tsx` | 30 | Display only | **NONE**: No form inputs |
---
## Unified Fix Strategy
### Solution: 3-Layer Modal Architecture
Replace the problematic single-layer pattern:
```tsx
// ❌ BROKEN: Single layer blocks dropdown menus
<div className="fixed inset-0 bg-black/50 flex items-center justify-center p-4 z-50">
<form>
<select> {/* BROKEN: Can't click */} </select>
</form>
</div>
```
With the 3-layer pattern:
```tsx
// ✅ FIXED: Separate layers for proper z-index stacking
<>
{/* Layer 1: Background overlay (z-40) */}
<div className="fixed inset-0 bg-black/50 z-40" onClick={onCancel} />
{/* Layer 2: Form container (z-50, pointer-events-none) */}
<div className="fixed inset-0 flex items-center justify-center p-4 pointer-events-none z-50">
{/* Layer 3: Form content (pointer-events-auto) */}
<div className="... pointer-events-auto">
<form className="pointer-events-auto">
<select> {/* WORKS: Dropdown renders above all layers */} </select>
</form>
</div>
</div>
</>
```
---
## Implementation Plan
### Phase 1: P0 Critical Components (4-6 hours)
**Priority Order** (most business-critical first):
1. **ProxyHostForm.tsx** (30 min) - Security policy assignment
2. **UsersPage.tsx** - InviteUserModal (20 min) - User management
3. **UsersPage.tsx** - EditPermissionsModal (30 min) - Permission management
4. **Uptime.tsx** - Both modals (45 min) - Monitor management
5. **RemoteServerForm.tsx** (20 min) - Infrastructure management
6. **CrowdSecConfig.tsx** - BanIPModal (20 min) - Security management
### Phase 2: P1 Components (1-2 hours)
Analysis and fix of remaining interactive modals if needed.
### Phase 3: Testing & Validation (2-3 hours)
- Manual testing of all dropdown interactions
- E2E test updates
- Cross-browser verification
**Total Estimated Time: 7-11 hours**
---
## Testing Strategy
### Manual Testing Checklist
For each P0 component:
- [ ] Modal opens correctly
- [ ] Background overlay click-to-close works
- [ ] All dropdown menus open and respond to clicks
- [ ] Dropdown options are selectable
- [ ] Form submission works with selected values
- [ ] ESC key closes modal
- [ ] Tab navigation works through form elements
### Automated Testing
**E2E Tests to Update:**
- `tests/integration/proxy-acl-integration.spec.ts` - ProxyHostForm dropdowns
- `tests/security/user-management.spec.ts` - UsersPage modals
- `tests/uptime/*.spec.ts` - Uptime monitor modals
- Any tests interacting with the affected modals
**Unit Tests:**
- Modal rendering tests should continue to pass
- Form submission tests should continue to pass
---
## Risk Assessment
**Risk Level: LOW-MEDIUM**
**Mitigating Factors:**
✅ Non-breaking change (only CSS/DOM structure)
✅ Identical fix pattern across all components
✅ Well-understood solution (already documented in ConfigReloadOverlay)
✅ Only affects modal presentation layer
**Risk Areas:**
⚠️ Multiple files being modified simultaneously
⚠️ Modal close behavior could be affected
⚠️ CSS specificity or responsive behavior could change
**Mitigation Strategy:**
- Fix components one at a time
- Test each component thoroughly before moving to next
- Keep changes minimal and focused
- Maintain existing CSS classes and styling
---
## Success Criteria
- [ ] All P0 modal dropdowns are clickable and functional
- [ ] Modal open/close behavior unchanged
- [ ] Background overlay click-to-close still works
- [ ] ESC key behavior unchanged
- [ ] All existing E2E tests pass
- [ ] No new console errors or warnings
- [ ] Cross-browser compatibility maintained (Chrome, Firefox, Safari, Edge)
---
## Implementation Notes
**CSS Classes to Add:**
- `pointer-events-none` on form container layers
- `pointer-events-auto` on form content elements
**CSS Classes to Modify:**
- Change overlay z-index from `z-50` to `z-40`
- Keep form container at `z-50`
**Accessibility:**
- Maintain `role="dialog"` and `aria-modal="true"` attributes
- Ensure Tab navigation still works correctly
- Preserve ESC key handling
---
## Post-Implementation Actions
1. **Documentation Update**: Update modal component patterns in design system docs
2. **Code Review Guidelines**: Add z-index modal pattern to code review checklist
3. **Linting Rule**: Consider ESLint rule to detect problematic modal patterns
4. **Design System**: Create reusable Modal component with correct z-index pattern
---
*This comprehensive fix addresses the root cause across the entire application, preventing future occurrences of the same issue.*