-
Notifications
You must be signed in to change notification settings - Fork 1
feat: add push_event support to modal for backend-initiated close/open #11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Code Review: Push Event Support for Modal ComponentI've reviewed PR #11 and here's my comprehensive feedback: StrengthsArchitecture & Design
Code Quality
Testing
Issues & Concerns1. Critical Bug: Missing Modal Element ReferenceThe refactoring removed the setupElements() code that finds the modal element. The hook now works directly on this.el (the portal element) instead of this.modalEl (the actual modal container). While this appears to work in tests, it changes the fundamental architecture where the hook was designed to operate on the modal element, not its portal. Questions to verify:
2. Test Coverage GapsThe new test only covers the close event. Consider adding tests for:
3. Potential Race ConditionIn handleModalOpen() and other handlers, the code calls this.ref() which queries this.el. If push events arrive before the DOM is fully initialized, this could fail silently. The maybeExecJS helper does check for null, which is good, but this could mask issues during async modal operations. 4. Documentation GapThe PR body mentions usage, but there's no documentation in the modal.ex module docs about push_event support. Consider adding a section about backend-initiated control. 5. Minor: CLAUDE.md UpdateThe addition to CLAUDE.md about not using sleep or setTimeout is good practice, but it's unrelated to this PR's core functionality. Consider moving it to a separate documentation PR. Suggestions for Improvement1. Add Event Payload SupportConsider extending the API to support targeting specific modals via event payloads, allowing the backend to target specific modals when multiple are present. 2. Test Edge CasesAdd tests for:
Security & PerformanceNo security concerns identified:
Performance is good:
RecommendationsMust Fix
Should Fix
Nice to Have
Overall AssessmentThis is a well-implemented feature that follows Prima's architecture patterns and maintains backward compatibility. The code quality is high, with proper cleanup and lifecycle management. The main concern is the architectural change around this.el vs this.modalEl which should be verified or documented. Recommendation: Approve with minor revisions to address the modalEl question and add documentation. Great work overall! The feature is useful and the implementation is clean. |
Pull Request ReviewSummaryThis PR successfully adds push_event support to the modal component, allowing backend-initiated modal control in frontend (non-async) mode. The implementation is well-structured with good test coverage. Strengths1. Clean Architecture
2. Code Clarity
3. Test Coverage
4. Documentation
Code Quality Observations1. Simplified Element References (assets/js/hooks/modal.js:30-35, 39-41) 2. Event Listener Cleanup (assets/js/hooks/modal.js:73-78) 3. Unified Event Handling Potential Issues1. Missing Target Selector for Push Events (IMPORTANT)
Recommendation: Add modal targeting by checking the payload for an id field. This would allow both targeted and broadcast behavior depending on whether an id is provided in the payload. 2. Test Coverage Gap 3. Documentation Gap Minor Suggestions1. Test Naming 2. Consider Adding to Demo Pages Security and PerformanceNo security concerns identified:
Performance is good:
Test ResultsThe PR mentions all tests pass (22 features + 1 test). This is excellent and shows good backward compatibility. Overall AssessmentThis is a high-quality PR that adds a useful feature with clean code and good test coverage. The main concern is the lack of modal targeting in push events (issue #1), which could cause unexpected behavior in multi-modal scenarios. Recommendation: Consider addressing issue #1 (modal targeting) before merging, as it affects the API design and would be a breaking change to fix later. The other suggestions are nice-to-haves that can be addressed in follow-up PRs. Great work overall! |
Code Review - Push Event Support for ModalGreat work on adding push_event support to the modal component! This is a useful feature that enables backend-initiated modal control. Strengths
Issues and Concerns1. Critical Architecture Issue: Redundant Event Handling The current implementation creates two separate event paths for the same events:
Both call the same handlers (handleModalOpen, handleModalClose), creating redundancy. I recommend having push event handlers dispatch DOM events that the existing listeners handle, maintaining a single code path for better clarity. 2. Removed modalEl Reference - Breaking Change? The PR removes the modalEl property entirely. The old code suggested the hook was attached to a -portal element but referenced a separate modal element. Now everything uses this.el. Is this simplification safe? The tests pass, but worth confirming this was intentional refactoring vs. a functional change. 3. Missing Documentation The PR should add documentation to lib/prima/modal.ex explaining the new push_event API with examples showing how to close/open specific modals or broadcast to all modals. 4. Test Quality - Minor Issues
Performance and SecurityPerformance: No concerns. The push event handlers are lightweight and properly cleaned up. Security: No concerns. The ID filtering prevents unintended modal targeting. Suggestions for Improvement
Minor Code Quality Notes
VerdictThis is solid work with good test coverage and clean implementation. My main recommendation is to refactor the push event handlers to dispatch DOM events rather than directly calling the handlers, which would simplify the architecture. The missing documentation should be added before merging. Recommendation: Request changes for documentation plus consider the architecture refactor suggestion. Testing Verification: All tests pass - 2 new test files with 5 features total, existing modal tests remain green, good coverage of edge cases. |
Code ReviewExcellent work on adding ✅ Strengths
🔍 Code Quality ObservationsJavaScript (modal.js)
Test Coverage (modal_push_event_test.exs)
Fixture File (modal_push_event_fixture.html.heex)
🐛 Potential Issues
🚀 Performance
🔒 SecurityNo security concerns identified. The event handling is scoped to the component and doesn't introduce XSS or injection risks. ✅ 📝 Documentation
🎯 RecommendationsHigh Priority
Medium Priority
Low Priority (Nice to Have)
✨ Overall AssessmentThis is a high-quality PR that follows repository conventions and introduces a valuable feature. The code is clean, well-tested, and maintains backward compatibility. The architectural decisions (separate setup methods, proper cleanup) demonstrate good engineering practices. The main recommendation is adding defensive checks for the payload object to prevent edge case failures. Everything else is minor polish. Recommendation: ✅ Approve with minor suggestions Great work! |
Code Review: Push Event Support for Modal ComponentThank you for this well-structured PR! The implementation adds valuable backend-initiated modal control while maintaining code quality. Here's my detailed feedback: ✅ StrengthsArchitecture & Design
Code Quality
🔍 Observations & Considerations1. Potential Event Listener DuplicationThe implementation now has both DOM event listeners AND push event listeners for the same events: // DOM listeners (lines 47-48)
[this.el, "prima:modal:open", this.handleModalOpen.bind(this)],
[this.el, "prima:modal:close", this.handleModalClose.bind(this)],
// Push event listeners (lines 25-34)
this.handleEvent("prima:modal:open", (payload) => {...})
this.handleEvent("prima:modal:close", (payload) => {...})Impact: When backend sends
This creates two execution paths to the same handlers. While this currently works, it's potentially confusing for future maintainers. Suggestion: Consider whether you need both paths, or if push events should be the single source of truth that dispatches DOM events for backward compatibility. 2. Missing Portal Element ReferenceThe PR removed this code: this.modalEl = document.getElementById(this.el.id.replace('-portal', ''))Question: Looking at
Verification needed: Please confirm that:
3. Event Naming ConsistencyThe events use the same name ( Alternative approach (for consideration): this.handleEvent("prima:modal:open", (payload) => {
// Dispatch DOM event for compatibility
this.el.dispatchEvent(new Event('prima:modal:open'))
})This makes the bridge between push events and DOM events explicit. 4. Error HandlingThe push event handlers don't include error handling: this.handleEvent("prima:modal:open", (payload) => {
if (\!payload.id || payload.id === this.el.id) {
this.handleModalOpen() // What if this throws?
}
})Suggestion: Consider wrapping handler calls in try-catch or ensuring they're defensive against DOM state issues. 🧪 Test CoverageExcellent Coverage
Potential Additions (Nice to Have)
📝 DocumentationThe PR description is excellent and includes:
Minor suggestion: Consider updating ## Backend Control
Modals can also be controlled from the backend using push_event:
def handle_event("action", _params, socket) do
{:noreply, push_event(socket, "prima:modal:close", %{})}
end
To target a specific modal when multiple are present:
{:noreply, push_event(socket, "prima:modal:open", %{id: "my-modal"})}🔒 SecurityNo security concerns identified. The implementation:
🎯 Performance
✏️ Minor Style Notes
🎉 SummaryThis is a high-quality PR that adds useful functionality with minimal risk. The code is clean, well-tested, and follows project conventions. Recommendation: ✅ Approve with minor suggestions The main items to address before merging:
Great work! 🚀 |
Pull Request ReviewOverviewThis PR successfully adds backend-initiated modal control via ✅ Strengths1. Architecture & Design
2. Code Quality
3. Test Coverage
🔍 Issues & Concerns1. Critical: Removed Modal Element Reference In // REMOVED CODE:
this.modalEl = document.getElementById(this.el.id.replace('-portal', ''))This was replaced by using Questions:
Impact: This could be a breaking change if there's any code relying on the portal/modal distinction, though it appears the hook is now attached to the modal element directly based on 2. Event Listener Target Change All DOM event listeners changed from // Before:
[this.modalEl, "prima:modal:open", ...]
// After:
[this.el, "prima:modal:open", ...]While this works, it changes which element the events bubble from/to. This should be explicitly tested for backward compatibility. 3. Push Event Handler Scope In if (\!payload.id || payload.id === this.el.id)Potential issue: If multiple modals are on the page and a push_event is sent without an ID, all modals will respond. While this might be intentional for a "close all" behavior, it should be:
4. Missing Documentation in Modal Hook The JavaScript hook file lacks JSDoc comments explaining the new push_event functionality. Consider adding:
5. Fixture Test Pattern In # Line 38 - sends "modal-one" as the id:
phx-click={JS.push("open-specific-modal", value: %{id: "modal-one"})}But the fixture handler expects the full portal ID? Let me verify by checking the actual implementation... Looking at the JavaScript, it checks 🎯 Suggestions1. Test Coverage Gaps Add tests for:
2. Error Handling Consider adding defensive checks: setupPushEventListeners() {
if (\!this.handleEvent) {
console.warn('[Prima Modal] handleEvent not available, push events disabled')
return
}
// ... rest of implementation
}3. Documentation Enhancements In # Close all frontend modals on the page
{:noreply, push_event(socket, "prima:modal:close", %{})}
# Close only a specific modal
{:noreply, push_event(socket, "prima:modal:close", %{id: "my-modal"})}4. Consider Return Values The 🔒 Security Considerations✅ No security concerns identified. The push_event mechanism is server-initiated only, so there's no risk of client-side injection or unauthorized modal manipulation. 📊 Performance Considerations✅ Minimal performance impact:
Minor optimization opportunity: The ID comparison happens on every push_event. For pages with many modals, consider early return: if (payload.id && payload.id \!== this.el.id) returnvs current: if (\!payload.id || payload.id === this.el.id) { ... }Though this is negligible in practice. 🎓 Best Practices ComplianceFollows CLAUDE.md guidelines:
Phoenix LiveView patterns:
📝 SummaryOverall Assessment: Approve with minor suggestions This is a well-implemented feature that adds valuable backend control capabilities to frontend modals. The code quality is good, test coverage is solid, and the documentation is helpful. Before merging, please clarify:
Nitpicks for future PRs:
Great work on maintaining backward compatibility while adding new functionality! 🚀 |
Pull Request ReviewSummaryThis PR adds push_event support to the modal component, enabling backend-initiated modal control. The implementation is well-designed and follows Prima's architecture patterns effectively. ✅ StrengthsArchitecture & Design:
Code Quality:
Testing:
🔍 Observations & Minor Suggestions1. Hook Element Reference Simplification The PR removes the modalEl reference and uses this.el directly throughout. This is a good simplification. The hook now operates directly on the portal element. This works because the hook is attached to the portal's inner div (the modal container itself), not the portal wrapper. 2. Event Dispatching Consistency In setupPushEventListeners(), handlers call handleModalOpen() directly, while in setupDOMEventListeners(), handlers are bound. Both approaches work since arrow functions preserve context. The inconsistency is noticeable but not problematic. 3. Test Coverage - Edge Cases The tests are comprehensive, but consider adding tests for:
4. Documentation Enhancement The moduledoc is excellent, but consider adding guidance on when to use frontend modals vs async modals:
5. Performance Consideration The push_event listeners are set up for every modal instance. The ID filtering happens at the JavaScript level for each modal. This is fine for typical use cases (most pages don't have dozens of modals), and the simpler approach is preferred over complex targeting. 🎯 Specific Code Feedbacklib/prima/modal.ex:
assets/js/hooks/modal.js:
demo/test/wallaby/demo_web/modal_push_event_test.exs:
🚀 Minor Enhancements to Consider (Optional)
🔒 Security & Accessibility
📊 Test Coverage AssessmentExcellent coverage includes:
Could add (nice-to-have):
🎓 Overall AssessmentThis is a high-quality PR that:
The implementation is production-ready. The minor observations above are suggestions for potential enhancements, not blockers. ✨ RecommendationApprove and merge with optional consideration of the minor suggestions above. This PR successfully extends Prima's modal component to support an important use case while maintaining the library's high quality standards. Great work! 🎉 |
Extend modal component to support closing and opening via push_event
from the backend in frontend (non-async) mode.
- Add handleEvent registration in modal hook for prima:modal:close
and prima:modal:open events
- Integrate push event listener setup/cleanup into initialize/cleanup
lifecycle methods
- Add fixture and Wallaby test demonstrating backend-initiated close
- Backend can now use push_event(socket, "prima:modal:close", %{})
to close frontend modals
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <[email protected]>
Rename for clarity to distinguish between DOM event listeners (addEventListener) and LiveView push event handlers (handleEvent). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
Add test to verify modal can be opened from backend using push_event, in addition to the existing close functionality. - Add test for prima:modal:open push_event - Add backend handler for open-frontend-modal event - Add backend-open-button to fixture 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
Allow backend to target specific modals via push_event payload,
enabling precise control when multiple modals are present.
- Add optional `id` field in push_event payload
- Hook checks payload and only responds if ID matches or is unspecified
- Maintains backward compatibility (empty payload targets all modals)
- Add fixture and tests demonstrating multiple modal targeting
Usage:
push_event(socket, "prima:modal:close", %{id: "user-modal"})
push_event(socket, "prima:modal:open", %{id: "settings-modal"})
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <[email protected]>
Consolidate frontend_modal_push_event and multiple_modals_push_event fixtures and tests into a unified modal_push_event fixture that demonstrates both single modal (no ID) and multi-modal (with ID) scenarios. - Merge two fixtures into modal_push_event_fixture.html.heex - Merge two test files into modal_push_event_test.exs - Update router and template to use single fixture route - All 26 features + 1 test still pass 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1bddb7a to
a60aade
Compare
|
Closing to create fresh PR with updated description |
PR Review: Push Event Support for Modal ComponentI've reviewed this PR and it's a high-quality implementation. Here's my detailed feedback: StrengthsArchitecture & Design
Documentation
Test Coverage
Code Quality
Potential Issues & Suggestions1. Edge Case: Rapid Event Triggering Recommendation: Consider adding state tracking (isOpening, isOpen, isClosing) to prevent race conditions. 2. Test Coverage Gap Expected: All modals should open (based on !payload.id check in modal.js:30) Recommendation: Add test case for this scenario. 3. Documentation Security & PerformanceSecurity: No concerns identified
Performance: Good characteristics
SummaryLGTM with minor suggestions Critical issues: None This is a well-implemented feature that solves a real use case with excellent documentation and test coverage. The suggested improvements are minor and don't block merging. |
Summary
This PR extends the modal component to support closing and opening via
push_eventfrom the backend in frontend (non-async) mode.Changes
handleEventregistration forprima:modal:closeandprima:modal:openeventsinitialize()/cleanup()lifecycle methodssetupEventListenerstosetupDOMEventListenersfor clarityUsage
Backend can now use
push_eventto control frontend modals:The modal hook receives the push_event and dispatches the corresponding DOM event to trigger the existing modal close logic.
Test Plan
frontend_modal_push_event_test.exs🤖 Generated with Claude Code