Content
View differences
Updated by Alexander Coles 2 days ago
## Summary
Migrate remaining list-shaped `Primer::Beta::BorderBox` / `border_box_container` usages to `OpenProject::Common::BorderBoxListComponent`, and extend `OpenProject::Common::BorderBoxListComponent` where the shared component API where already matches the remaining migrations needed legitimate header flexibility. behavior.
Implementation `Documents::Admin::DocumentTypes::IndexComponent` is tracked in intentionally excluded from this follow-up. It should be handled together with PR opf/openproject#23812. opf/openproject#23485 / WP#74940 because it belongs to the same `Admin::Enumerations::IndexComponent` class hierarchy.
## Implemented so far Strong candidates
### Shared component API
- Added `header.with_title` for linked or composed title content while still rendering inside the configured heading element. `app/components/settings/project_phase_definitions/index_component.html.erb` - header, empty row, draggable/filterable rows.
- Added `header.with_action_icon_button` for icon-only `app/components/projects/settings/life_cycle/index_component.html.erb` - header actions. actions, empty row, filterable rows.
- Reworked header/row menus through `BorderBoxListComponent::Menu`, keeping the default kebab trigger automatic while allowing `button_arguments:` or a caller-provided `menu.with_show_button`. `app/components/projects/settings/project_custom_field_sections/show_component.html.erb` - header actions, empty row, repeated rows.
- Added default empty-state rendering for itemless lists when callers do not provide a `app/components/projects/settings/creation_wizard/project_custom_field_sections/show_component.html.erb` - same pattern as project custom `with_empty_state` slot. field sections.
- Updated Lookbook docs, previews, preview specs, `app/components/oauth/applications/index_component.html.erb` - simple application lists with headers and component specs for the new public API. placeholder rows.
- `app/components/portfolios/index_component.html.erb` - simple portfolio list with optional placeholder row.
### Migrated consumers ## Good candidates requiring extra verification
- `Wikis::CollapsiblePageLinksComponent`
`app/components/work_package_types/export_template_list_component.html.erb` - `Wikis::RelationPageLinksComponent` drag-and-drop rows; verify DnD selectors.
- `Portfolios::IndexComponent`
`app/components/workflows/table_component.html.erb` - `OAuth::Applications::IndexComponent` list-shaped despite the name; verify filter target behavior.
- `Settings::ProjectPhaseDefinitions::IndexComponent`
`modules/wikis/app/components/wikis/collapsible_page_links_component.html.erb` - `Projects::Settings::LifeCycle::IndexComponent` maps to collapsible list; verify collapsed state and count behavior.
- `Projects::Settings::ProjectCustomFieldSections::ShowComponent`
`modules/wikis/app/components/wikis/relation_page_links_component.html.erb` - `Projects::Settings::CreationWizard::ProjectCustomFieldSections::ShowComponent` header action menu plus login/blank/list rows; map custom header actions carefully.
- `Workflows::TypeListComponent`, renamed from `Workflows::TableComponent`
`modules/meeting/app/components/work_package_meetings_tab/meeting_component.html.erb` - `WorkPackageTypes::ExportTemplateListComponent` header plus agenda item rows; preserve custom header content.
- `My::Notifications::ShowPageComponent`
`app/components/admin/departments/detail_component.html.erb` - `WorkPackageMeetingsTab::MeetingComponent` breadcrumbs/action header plus mixed rows; verify header mapping.
- `Admin::Departments::DetailComponent`
`app/components/my/notifications/show_page_component.html.erb` - `WorkPackageRelationsTab::IndexComponent` project-specific notification settings list.
Existing Backlogs bucket/sprint menu callers were also updated to the new `button_arguments:` API.
## Review and commit structure Lower priority / more invasive
The branch was regrouped for reviewability: These are list-shaped but pass the BorderBox container into children, use sensitive drag-and-drop contracts, or have more specialized rendering:
- the shared API change is now the first commit; `modules/meeting/app/components/meeting_sections/show_component.html.erb`
- each consumer migration is committed as a focused vertical slice; `app/components/shares/manage_shares_component.html.erb`
- follow-up review fixes were folded into their owning commits rather than left as a trailing cleanup commit; `app/components/work_package_relations_tab/index_component.rb`
- every `[DREAM-697]` commit has a one-line detail and links back to this work package. `app/components/work_package_types/form_configuration/group_component.html.erb`
- `app/components/admin/custom_fields/hierarchy/items_component.html.erb`
## Verification Not good initial fits
Do not prioritize activity journal/comment boxes using `with_body`, date-picker relation-tab mini boxes, health report result groups, Jira wizard step grouping, or single presentation-mode wrappers. They use BorderBox, but are not straightforward reusable list composition cases.
## Re-assessment (2026-06-18)
Re-checked the three flagged candidates against the current `BorderBoxListComponent` slots (header: title / count / description / action *buttons* / kebab *menu* via `HasMenu` / collapsible; `item` + `work_package_item` rows; `empty_state`; `footer`).
- Component specs for **`app/components/workflows/table_component.html.erb`** - clean strong fit, not just "requires verification". Header h2 title, per-type rows with inline edit/copy ActionMenu, empty Blankslate. The `filter--filter-list-target: searchItem` data attribute on each row survives because `Item` forwards `system_arguments` to Primer's row. Separately: the shared component and migrated consumers: 195 examples, 0 failures. is list-shaped, so `Workflows::TableComponent` should be renamed to `Workflows::TypeListComponent` (own change, not part of the migration).
- Feature specs for workflow accessibility and export-template drag/toggle behavior: 4 examples, 0 failures.
**`modules/wikis/app/components/wikis/collapsible_page_links_component.html.erb`** - `bin/dirty-rubocop --against origin/dev`: 27 files, no offenses. stronger than "requires verification". Already uses `CollapsibleHeader(collapsed: true)` + count + `PageLinkComponent` rows; maps 1:1 to `collapsible: true`, `collapsed: true`, `header_padding: :condensed`, `count: page_links.count`, `item` rows.
- `erb_lint` on changed ERB files: no errors.
**`modules/wikis/app/components/wikis/relation_page_links_component.html.erb`** - `git diff --check origin/dev..HEAD`: clean.
## Deferred / out of scope
`Documents::Admin::DocumentTypes::IndexComponent` remains intentionally excluded real blocker, not just "map carefully". The header menu uses a custom ActionMenu show button (plus icon + triangle-down + text label + `disabled: !can_manage_links?`). `HasMenu#build_menu` hardcodes a kebab-horizontal invisible show button and should the `actions` slot only renders `Primer::Beta::Button`, so the header cannot be handled with PR opf/openproject#23485 / WP#74940 because it belongs expressed today. Needs a `Header` extension to allow show-button customization, otherwise keep the same `Admin::Enumerations::IndexComponent` class hierarchy. header hand-rolled.
More invasive or less direct BorderBox usages remain out of scope for this PR, including meeting section boxes, manage-shares rendering, form-configuration groups, Both wikis components are recent (`#73352` / `#73354`) and custom-field hierarchy items. still churning, so converting them now risks conflicts.
Migrate
Implementation
## Implemented so far
### Shared component API
- Added `header.with_title` for linked or composed title content while still rendering inside the configured heading element.
- Added `header.with_action_icon_button` for icon-only
- Reworked header/row menus through `BorderBoxListComponent::Menu`, keeping the default kebab trigger automatic while allowing `button_arguments:` or a caller-provided `menu.with_show_button`.
- Added default empty-state rendering for itemless lists when callers do not provide a
- Updated Lookbook docs, previews, preview specs,
- `app/components/portfolios/index_component.html.erb` - simple portfolio list with optional placeholder row.
### Migrated consumers
- `Wikis::CollapsiblePageLinksComponent`
- `Portfolios::IndexComponent`
- `Settings::ProjectPhaseDefinitions::IndexComponent`
- `Projects::Settings::ProjectCustomFieldSections::ShowComponent`
- `Workflows::TypeListComponent`, renamed from `Workflows::TableComponent`
- `My::Notifications::ShowPageComponent`
- `Admin::Departments::DetailComponent`
Existing Backlogs bucket/sprint menu callers were also updated to the new `button_arguments:` API.
## Review and commit structure
The branch was regrouped for reviewability:
- the shared API change is now the first commit;
- each consumer migration is committed as a focused vertical slice;
- follow-up review fixes were folded into their owning commits rather than left as a trailing cleanup commit;
- every `[DREAM-697]` commit has a one-line detail and links back to this work package.
- `app/components/admin/custom_fields/hierarchy/items_component.html.erb`
## Verification
## Re-assessment (2026-06-18)
Re-checked the three flagged candidates against the current `BorderBoxListComponent` slots (header: title / count / description / action *buttons* / kebab *menu* via `HasMenu` / collapsible; `item` + `work_package_item` rows; `empty_state`; `footer`).
- Feature specs for workflow accessibility and export-template drag/toggle behavior: 4 examples, 0 failures.
- `erb_lint` on changed ERB files: no errors.
## Deferred / out of scope
`Documents::Admin::DocumentTypes::IndexComponent` remains intentionally excluded
More invasive or less direct BorderBox usages remain out of scope for this PR, including meeting section boxes, manage-shares rendering, form-configuration groups,