Skip to content

[OP-19415] Convert FilterForm to ViewComponent - #23488

Merged
myabc merged 6 commits into
devfrom
code-maintenance/75446-filters-form-component-rework
Jun 3, 2026
Merged

[OP-19415] Convert FilterForm to ViewComponent#23488
myabc merged 6 commits into
devfrom
code-maintenance/75446-filters-form-component-rework

Conversation

@myabc

@myabc myabc commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Ticket

https://community.openproject.org/wp/OP-19415

What are you trying to accomplish?

Replaces Filters::FilterForm (an ApplicationForm subclass) with Filters::FilterFormComponent (an ApplicationComponent). The old form overrode :nodoc: Primer hooks (before_render, perform_render) and read semi-public ivars (@builder, @view_context). The new component receives the builder as an explicit keyword arg and uses a standard ERB template, reducing Primer internal coupling from five semi-public APIs to one (FormList).

Screenshots

No visible changes.

What approach did you choose and why?

The component builds its controller wrapper with merge_data, but upstream Primer::AttributesHelper does not treat controller as a plural data attribute, so a caller-supplied data-controller was silently overwritten by the required filter--filters-form controller. Added OpPrimer::AttributesHelper, which includes the upstream helper and overrides only merge_data to treat controller as plural — multiple Stimulus controllers now concatenate (data-controller="a b") instead of clobbering. The component includes this helper in place of the Primer one.

Merge checklist

  • Added/updated tests
  • Added/updated documentation in Lookbook (patterns, previews, etc)
  • Tested major browsers (Chrome, Firefox, Edge, ...)

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors the filters UI building block by replacing the former Filters::FilterForm (a Primer ApplicationForm) with Filters::FilterFormComponent (a ViewComponent), passing the form builder explicitly and rendering via a standard ERB template to reduce coupling to Primer internals.

Changes:

  • Introduces Filters::FilterFormComponent as an ApplicationComponent, including a dedicated .html.erb template, while keeping the existing filter-row composition via Primer::Forms::FormList.
  • Updates Filter::FilterComponent, Lookbook previews/docs, and specs to instantiate and render the new component with builder:.
  • Adjusts related inline documentation/comments to reference the new component name.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated no comments.

Show a summary per file
File Description
spec/components/filters/filter_form_component_spec.rb Updates component spec to exercise Filters::FilterFormComponent and its builder keyword arg.
lookbook/previews/open_project/filter/filter_form_preview/with_hidden_input.html.erb Switches preview rendering to Filters::FilterFormComponent.new(builder: ...).
lookbook/previews/open_project/filter/filter_form_preview/with_active_filter.html.erb Switches preview rendering to the new component API.
lookbook/previews/open_project/filter/filter_form_preview/for_a_work_package_query.html.erb Updates legacy Query preview comments and rendering to use the component.
lookbook/previews/open_project/filter/filter_form_preview/default.html.erb Updates default preview to render the component with builder:.
lookbook/previews/open_project/filter/filter_form_preview/combined_with_other_inputs.html.erb Updates composed FormList preview to include the component alongside forms.
lookbook/docs/patterns/11-filter-forms.md.erb Renames and updates documentation from FilterForm to FilterFormComponent.
app/models/query.rb Updates references in comments to the new component name.
app/models/queries/work_packages/filter/filter_for_wp_mixin.rb Updates comment describing which UI dispatch renders these filters.
app/components/filters/filter_form_component.rb Converts implementation from Primer form object to ApplicationComponent with explicit builder: and helper-based rendering.
app/components/filters/filter_form_component.html.erb Adds ERB template implementing wrapper/hidden-input rendering logic.
app/components/filter/filter_component.rb Updates filter_form to return Filters::FilterFormComponent with builder:.

@myabc
myabc requested review from HDinger and dfriquet June 1, 2026 14:03
@myabc
myabc marked this pull request as ready for review June 2, 2026 10:52
@myabc myabc added maintenance ruby Pull requests that update Ruby code needs review labels Jun 2, 2026
@myabc myabc changed the title [#75446] Convert FilterForm to ViewComponent [OP-19415] Convert FilterForm to ViewComponent Jun 2, 2026
@myabc
myabc force-pushed the code-maintenance/75446-filters-form-component-rework branch from ed2cd0c to f6700cc Compare June 2, 2026 15:16
myabc added 4 commits June 2, 2026 18:50
Replaces `Filters::FilterForm` (an `ApplicationForm` subclass) with
`Filters::FilterFormComponent` (an `ApplicationComponent`). The old form
overrode `:nodoc:` Primer hooks (`before_render`, `perform_render`) and
read semi-public ivars (`@builder`, `@view_context`). The new component
receives the builder as an explicit keyword arg and uses a standard ERB
template, reducing Primer internal coupling from five semi-public APIs
to one (`FormList`).

https://community.openproject.org/wp/OP-19415
Uses `ConditionalWrapper` to eliminate template duplication in the
`wrap_with_controller` branch, and `merge_data` from
`Primer::AttributesHelper` for Stimulus data attributes.

https://community.openproject.org/wp/OP-19415
@myabc
myabc force-pushed the code-maintenance/75446-filters-form-component-rework branch from f6700cc to a9742d0 Compare June 2, 2026 17:01
myabc added 2 commits June 2, 2026 19:05
Stimulus supports multiple controllers on one element, but Primer's
`merge_data` is not controller-aware and silently drops a caller's
`data-controller` when a component merges in its own. Treat `controller`
as a plural data attribute so the values concatenate instead.
Use OpPrimer::AttributesHelper so a caller-supplied data-controller is
concatenated with the required filter--filters-form controller instead of
being overwritten. The wrapper spec now asserts both controllers survive.
@myabc myabc added this to the 17.6.x milestone Jun 2, 2026

@HDinger HDinger left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code changes look good to me. 👍 I am not 100% sure whether the CI failures might be related.

Comment on lines +38 to +45
module AttributesHelper
include Primer::AttributesHelper

PLURAL_DATA_ATTRIBUTES = (Primer::AttributesHelper::PLURAL_DATA_ATTRIBUTES + %i[controller]).freeze

def merge_data(*hashes)
merge_prefixed_attribute_hashes(*hashes, prefix: :data, plural_keys: PLURAL_DATA_ATTRIBUTES)
end

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could also think about moving that to the PVC repo directly...

@myabc

myabc commented Jun 3, 2026

Copy link
Copy Markdown
Contributor Author

I am not 100% sure whether the CI failures might be related.

I don't seem to be able to get a green build, but also can't reproduce these failures locally.

@myabc
myabc merged commit 71c3cec into dev Jun 3, 2026
15 of 18 checks passed
@myabc
myabc deleted the code-maintenance/75446-filters-form-component-rework branch June 3, 2026 13:58
@github-actions github-actions Bot locked and limited conversation to collaborators Jun 3, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

maintenance needs review ruby Pull requests that update Ruby code

Development

Successfully merging this pull request may close these issues.

3 participants