Restructure 7 modal components to use 3-layer architecture preventing native select dropdown menus from being blocked by modal overlays. Components fixed: - ProxyHostForm: ACL selector and Security Headers dropdowns - User management: Role and permission mode selection - Uptime monitors: Monitor type selection (HTTP/TCP) - Remote servers: Provider selection dropdown - CrowdSec: IP ban duration selection The fix separates modal background overlay (z-40) from form container (z-50) and enables pointer events only on form content, allowing native dropdown menus to render above all modal layers. Resolves user inability to select security policies, user roles, monitor types, and other critical configuration options through the UI interface.
206 lines
7.4 KiB
Markdown
206 lines
7.4 KiB
Markdown
# 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.* |