.vbw-planning/milestones/07-rails-audit-and-refactoring/07-rails-audit-round-2/04-PLAN.md
Key context: Status badge markup (inline-flex items-center rounded-full with conditional colors/spinners) is duplicated 12+ times across sources, items, dashboard, and logs views. The engine already has IconComponent as a ViewComponent pattern to follow. Modals are plain divs without WCAG dialog attributes. Items _details.html.erb and _bulk_scrape_modal.html.erb execute database queries directly. Items and Logs index pages duplicate pagination markup instead of using the shared _pagination partial. </context> <tasks> <task type="auto"> <name>Create StatusBadgeComponent (M20)</name> <files> app/components/source_monitor/status_badge_component.rb app/components/source_monitor/status_badge_component.html.erb test/components/source_monitor/status_badge_component_test.rb </files> <action>
status (string/symbol) and optional size parameter.Note: Be careful to preserve the exact status value being displayed. Some views may use fetch_status, health_status, scrape_status, or custom status strings. The component should accept all of these. </action> <verify> bin/rails test test/controllers/ test/system/ -- existing view tests still pass </verify> <done> All inline badge markup replaced with StatusBadgeComponent. No hand-crafted badge spans remain in view templates. </done> </task> <task type="auto"> <name>Add modal accessibility and focus trapping (M22+M23)</name> <files> app/views/source_monitor/sources/_bulk_scrape_modal.html.erb app/views/source_monitor/sources/_bulk_scrape_enable_modal.html.erb app/assets/javascripts/source_monitor/controllers/modal_controller.js </files> <action>
role="dialog", aria-modal="true", and aria-labelledby (pointing to the modal heading's ID) to both modal template root elements.inert attribute on sibling elements of the modal (elements behind the backdrop).inert from those elements.inert is not well-supported, use a tabindex-based approach that captures Tab and Shift+Tab at the modal boundaries.Note: Check if FilterDropdownComponent is a ViewComponent or a helper method. If it's a ViewComponent, modify the component file (which is in Plan 04's file set). If it generates HTML via a helper, modify application_helper.rb. </action> <verify> bin/rails test test/controllers/source_monitor/logs_controller_test.rb </verify> <done> FilterDropdown uses Stimulus action instead of inline onchange. Logs index has Turbo Frame for filter/pagination. </done> </task> </tasks> <verification>
<success_criteria>
04-SUMMARY.md </output>