[#73968] Add card box item bridge

Extracts the BorderBox row arguments into a row-bridge object
(`WorkPackageCardBoxComponent::Item`) so the box can build rows without
forcing the visual card to render row-level concerns. The visual
`WorkPackageCardComponent` constructor narrows to
`(work_package:, menu_src:)`; in-repo callers updated.

Adds a polymorphic slot API (`with_work_package_item`,
`with_empty_item`) modeled on `Primer::Alpha::FileTreeView`, plus a
public `#build_item` for off-box callers. Renames the URL pass-through
to a generic `params:` kwarg, leaving Backlogs all-state handling at the
call sites.

https://community.openproject.org/wp/73968
This commit is contained in:
Alexander Brandon Coles
2026-05-01 16:43:09 +02:00
parent f60146aa45
commit 60bb8e1ea9
14 changed files with 951 additions and 282 deletions
@@ -32,6 +32,8 @@ module OpenProject
module Common
# @logical_path OpenProject/Common
class WorkPackageCardBoxComponentPreview < ViewComponent::Preview
include ActionView::RecordIdentifier
def sprint_with_cards
sprint = Sprint.first
project = sprint&.project
@@ -69,7 +71,9 @@ module OpenProject
return preview_message("No project in the database.") unless project
render OpenProject::Common::WorkPackageCardBoxComponent.new(
work_packages: [], project:, container: nil
work_packages: [],
project:,
container: dom_target(:inbox, project)
) do |box|
box.with_empty_state(title: "Inbox is empty", description: "All caught up",
icon: :"op-backlogs")
@@ -94,7 +98,9 @@ module OpenProject
end
render OpenProject::Common::WorkPackageCardBoxComponent.new(
work_packages:, project:, container: nil
work_packages:,
project:,
container: dom_target(:inbox, project)
) do |box|
box.with_empty_state(title: "Inbox is empty", description: "All caught up", icon: :"op-backlogs")
box.with_show_more(truncate_middle: 50)
@@ -34,26 +34,10 @@ module OpenProject
class WorkPackageCardComponentPreview < ViewComponent::Preview
def default
work_package = WorkPackage.first
project = work_package&.project
return preview_message("No work packages in the database.") unless work_package && project
sprint = Sprint.where(project_id: project.id).first
render OpenProject::Common::WorkPackageCardComponent.new(
work_package:,
project:,
container: sprint
)
end
def inbox_context
work_package = WorkPackage.first
project = work_package&.project
return preview_message("No work packages in the database.") unless work_package && project
return preview_message("No work packages in the database.") unless work_package
render OpenProject::Common::WorkPackageCardComponent.new(
work_package:,
project:,
container: nil
work_package:
)
end