mirror of
https://github.com/opf/openproject.git
synced 2026-06-14 03:30:14 +00:00
Extend the WorkPackageCardComponent with new optionss
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
The `WorkPackageCard` is a compact representation of a work package, designed for use in list and board views such as sprint and backlog views.
|
||||
|
||||
## Overview
|
||||
|
||||
<%= embed OpenProject::Common::WorkPackageCardComponentPreview, :default %>
|
||||
|
||||
## Anatomy
|
||||
|
||||
The card is structured in up to three rows:
|
||||
|
||||
**Row 1 — Metadata**
|
||||
Contains the info line (type, ID, status), followed by optional elements: assignee, metric (e.g. story points), priority, and the actions menu. When `show_drag_handle: true`, a drag handle icon appears on the far left, spanning all rows, aligned to the top (row 1).
|
||||
|
||||
**Row 2 — Subject**
|
||||
The work package title, always visible.
|
||||
|
||||
**Row 3 — Footer** *(only rendered when content is present)*
|
||||
Shows a link to the parent work package (when `show_parent_link: true` and a parent exists) and/or the `with_bottom_line` slot.
|
||||
|
||||
## Parameters
|
||||
|
||||
| Parameter | Type | Default | Description |
|
||||
|---|---|---|---|
|
||||
| `work_package` | `WorkPackage` | required | The work package to display |
|
||||
| `menu_src` | `String` | `nil` | Optional lazy-load URL for the actions menu |
|
||||
| `show_assignee` | `Boolean` | `false` | Show the assignee icon and name |
|
||||
| `show_priority` | `Boolean` | `false` | Show a priority badge |
|
||||
| `show_drag_handle` | `Boolean` | `false` | Show a drag handle icon |
|
||||
| `show_parent_link` | `Boolean` | `false` | Show a link to the parent work package in row 3. Only rendered when `work_package.parent` is present. |
|
||||
| `status_scheme` | `Symbol` | `:default` | Status label style: `:default` (highlighted) or `:secondary` (neutral label) |
|
||||
|
||||
## Slots
|
||||
|
||||
| Slot | Description |
|
||||
|---|---|
|
||||
| `with_metric` | Numeric value shown in row 1 (e.g. story points) |
|
||||
| `with_menu` | Custom actions menu, replaces the default lazy menu |
|
||||
| `with_bottom_line` | Additional content appended to row 3 |
|
||||
|
||||
## Variants
|
||||
|
||||
<%= embed OpenProject::Common::WorkPackageCardComponentPreview, :playground, panels: %i[params source] %>
|
||||
|
||||
## Code structure
|
||||
|
||||
```ruby
|
||||
render OpenProject::Common::WorkPackageCardComponent.new(
|
||||
work_package: @work_package,
|
||||
show_assignee: true,
|
||||
show_priority: true,
|
||||
show_parent_link: true,
|
||||
status_scheme: :secondary
|
||||
) do |card|
|
||||
card.with_metric { @work_package.story_points }
|
||||
card.with_menu do |menu|
|
||||
menu.with_item(label: "Open", href: work_package_path(@work_package))
|
||||
end
|
||||
card.with_bottom_line do
|
||||
# Whatever else you want to show
|
||||
end
|
||||
end
|
||||
```
|
||||
@@ -32,37 +32,99 @@ module OpenProject
|
||||
module Common
|
||||
# @logical_path OpenProject/Common
|
||||
class WorkPackageCardComponentPreview < ViewComponent::Preview
|
||||
# See the [component documentation](/lookbook/pages/components/work_packages/card) for more details.
|
||||
#
|
||||
# @param show_assignee toggle
|
||||
# @param show_priority toggle
|
||||
# @param show_drag_handle toggle
|
||||
# @param show_parent_link toggle
|
||||
# @param show_metric toggle
|
||||
# @param show_menu toggle
|
||||
# @param show_bottom toggle
|
||||
# @param status_scheme select [default, secondary]
|
||||
def playground(show_assignee: false, show_priority: false, show_drag_handle: false,
|
||||
show_parent_link: false, show_metric: false, show_menu: false,
|
||||
show_bottom: false, status_scheme: :default)
|
||||
work_package = WorkPackage.visible.where.not(parent_id: nil).first || WorkPackage.visible.first
|
||||
return preview_message("No work packages in the database.") unless work_package
|
||||
|
||||
render_with_template(template: "open_project/common/work_package_card_component_preview/playground",
|
||||
locals: {
|
||||
work_package:,
|
||||
show_assignee:,
|
||||
show_priority:,
|
||||
show_drag_handle:,
|
||||
show_parent_link:,
|
||||
show_metric:,
|
||||
show_menu:,
|
||||
show_bottom:,
|
||||
status_scheme:
|
||||
})
|
||||
end
|
||||
|
||||
# Minimal card showing only the info line, subject and actions menu.
|
||||
def default
|
||||
work_package = WorkPackage.first
|
||||
work_package = WorkPackage.visible.first
|
||||
return preview_message("No work packages in the database.") unless work_package
|
||||
|
||||
render OpenProject::Common::WorkPackageCardComponent.new(work_package:)
|
||||
end
|
||||
|
||||
# Card with a numeric metric (e.g. story points) in the top-right area.
|
||||
def with_metric
|
||||
work_package = WorkPackage.visible.first
|
||||
return preview_message("No work packages in the database.") unless work_package
|
||||
|
||||
render OpenProject::Common::WorkPackageCardComponent.new(work_package:) do |card|
|
||||
card.with_metric { (work_package.try(:story_points) || 8).to_s }
|
||||
end
|
||||
end
|
||||
|
||||
# Card with a custom actions menu.
|
||||
def with_menu
|
||||
work_package = WorkPackage.visible.first
|
||||
return preview_message("No work packages in the database.") unless work_package
|
||||
|
||||
render OpenProject::Common::WorkPackageCardComponent.new(work_package:) do |card|
|
||||
card.with_menu do |menu|
|
||||
menu.with_item(label: "Open", href: "/work_packages/#{work_package.id}")
|
||||
menu.with_item(label: "Edit", href: "/work_packages/#{work_package.id}/edit")
|
||||
menu.with_divider
|
||||
menu.with_item(label: "Delete", scheme: :danger)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Card with a drag handle icon for reorderable lists.
|
||||
def with_drag_handle
|
||||
work_package = WorkPackage.visible.first
|
||||
return preview_message("No work packages in the database.") unless work_package
|
||||
|
||||
render OpenProject::Common::WorkPackageCardComponent.new(
|
||||
work_package:
|
||||
work_package:,
|
||||
show_drag_handle: true
|
||||
)
|
||||
end
|
||||
|
||||
def with_metric
|
||||
work_package = WorkPackage.first
|
||||
return preview_message("No work packages in the database.") unless work_package
|
||||
# Card with show_parent_link enabled. Renders a link to the parent work package in row 3.
|
||||
# Only visible when the work package actually has a parent.
|
||||
def with_parent_link
|
||||
work_package = WorkPackage.visible.where.not(parent_id: nil).first
|
||||
return preview_message("No work packages with a parent found.") unless work_package
|
||||
|
||||
render OpenProject::Common::WorkPackageCardComponent.new(
|
||||
work_package:
|
||||
) do |card|
|
||||
card.with_metric_content(10)
|
||||
end
|
||||
work_package:,
|
||||
show_parent_link: true
|
||||
)
|
||||
end
|
||||
|
||||
def with_menu
|
||||
work_package = WorkPackage.first
|
||||
# Card with additional content in the bottom slot (row 3), rendered alongside the parent link.
|
||||
def with_bottom_line
|
||||
work_package = WorkPackage.visible.first
|
||||
return preview_message("No work packages in the database.") unless work_package
|
||||
|
||||
render OpenProject::Common::WorkPackageCardComponent.new(
|
||||
work_package:
|
||||
) do |card|
|
||||
card.with_menu do |menu|
|
||||
menu.with_item(label: "Open", href: "/work_packages/#{work_package.id}")
|
||||
end
|
||||
end
|
||||
render_with_template(template: "open_project/common/work_package_card_component_preview/with_bottom_line",
|
||||
locals: { work_package: })
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
<%= render OpenProject::Common::WorkPackageCardComponent.new(
|
||||
work_package:,
|
||||
show_assignee:,
|
||||
show_priority:,
|
||||
show_drag_handle:,
|
||||
show_parent_link:,
|
||||
status_scheme: status_scheme.to_sym
|
||||
) do |card|
|
||||
card.with_metric { (work_package.try(:story_points) || 5).to_s } if show_metric
|
||||
|
||||
if show_menu
|
||||
card.with_menu do |menu|
|
||||
menu.with_item(label: "Open", href: "/work_packages/#{work_package.id}")
|
||||
menu.with_item(label: "Edit", href: "/work_packages/#{work_package.id}/edit")
|
||||
menu.with_divider
|
||||
menu.with_item(label: "Delete", scheme: :danger)
|
||||
end
|
||||
end
|
||||
|
||||
if show_bottom
|
||||
card.with_bottom_line do
|
||||
render(Primer::Beta::Text.new(tag: :span, font_size: :small, color: :subtle)) { "Some bottom line" }
|
||||
end
|
||||
end
|
||||
end %>
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
<%= render OpenProject::Common::WorkPackageCardComponent.new(work_package:) do |card|
|
||||
card.with_bottom_line do
|
||||
render(Primer::Beta::Text.new(tag: :span, font_size: :small, color: :subtle)) { "Some bottom line" }
|
||||
end
|
||||
end %>
|
||||
Reference in New Issue
Block a user