diff --git a/app/components/open_project/common/work_package_card_component.html.erb b/app/components/open_project/common/work_package_card_component.html.erb
index 0b879b92a1e9..ce8ac93262c0 100644
--- a/app/components/open_project/common/work_package_card_component.html.erb
+++ b/app/components/open_project/common/work_package_card_component.html.erb
@@ -30,20 +30,43 @@ See COPYRIGHT and LICENSE files for more details.
<%= grid_layout(
"op-work-package-card",
tag: :article,
- classes: { "op-work-package-card_with-metric": metric? }
+ classes: layout_classes
) do |grid| %>
+ <% if show_drag_handle %>
+ <% grid.with_area(:drag_handle, classes: "hide-when-print") do %>
+ <%= render(Primer::OpenProject::DragHandle.new) %>
+ <% end %>
+ <% end %>
+
<% grid.with_area(:info_line) do %>
- <%# TODO(73089): allow callers to pass arguments through to InfoLineComponent (e.g. status presentation, variants). %>
- <%= render(WorkPackages::InfoLineComponent.new(work_package:)) %>
+ <%= render(WorkPackages::InfoLineComponent.new(work_package:, status_scheme:)) %>
<% end %>
- <% if metric? %>
- <% grid.with_area(:metric) do %>
- <%= metric %>
+ <% grid.with_area(:actions) do %>
+ <% if show_assignee && work_package.assigned_to %>
+ <%= render(
+ Users::AvatarComponent.new(
+ user: work_package.assigned_to, size: "mini", link: false, show_name: true,
+ name_classes: "op-work-package-card--assignee-name"
+ )
+ ) %>
+ <% end %>
+
+ <% if metric? %>
+ <%= metric %>
+ <% end %>
+
+ <% if show_priority && work_package.priority %>
+ <%= render(
+ Primer::Beta::Text.new(
+ tag: :span,
+ classes: "__hl_inline_priority_#{work_package.priority.id} __hl_inline__small_dot"
+ )
+ ) do %>
+ <%= work_package.priority.name %>
+ <% end %>
<% end %>
- <% end %>
- <% grid.with_area(:menu) do %>
<% if menu? %>
<%= menu %>
<% else %>
@@ -58,6 +81,39 @@ See COPYRIGHT and LICENSE files for more details.
<% end %>
<% grid.with_area(:subject) do %>
- <%= render(Primer::Beta::Text.new(font_weight: :semibold)) { work_package.subject } %>
+ <% if link_subject %>
+ <%= render(Primer::Beta::Link.new(href: work_package_path(work_package), font_weight: :semibold)) { work_package.subject } %>
+ <% else %>
+ <%= render(Primer::Beta::Text.new(font_weight: :semibold)) { work_package.subject } %>
+ <% end %>
+ <% end %>
+
+ <% if show_footer? %>
+ <% grid.with_area(:footer) do %>
+ <% flex_layout do |flex| %>
+ <% if show_parent? %>
+ <% flex.with_row do %>
+ <%= render(Primer::Beta::Text.new(color: :muted, font_size: :small)) do %>
+ <%= "#{t('.parent')}: " %>
+ <%= render(
+ Primer::Beta::Link.new(
+ href: work_package_path(work_package.parent),
+ underline: false,
+ color: :default
+ )
+ ) do %>
+ <%= work_package.parent.subject %>
+ <% end %>
+ <% end %>
+ <% end %>
+ <% end %>
+
+ <% if additional_details? %>
+ <% flex.with_row do %>
+ <%= additional_details %>
+ <% end %>
+ <% end %>
+ <% end %>
+ <% end %>
<% end %>
<% end %>
diff --git a/app/components/open_project/common/work_package_card_component.rb b/app/components/open_project/common/work_package_card_component.rb
index 224f342a9089..ac7f4af02147 100644
--- a/app/components/open_project/common/work_package_card_component.rb
+++ b/app/components/open_project/common/work_package_card_component.rb
@@ -43,17 +43,54 @@ class WorkPackageCardComponent < ApplicationComponent
**system_arguments
)
}
+ renders_one :additional_details, Primer::Content
- attr_reader :work_package, :menu_src
+ attr_reader :work_package, :menu_src, :show_drag_handle, :show_assignee, :show_priority,
+ :show_parent, :link_subject, :status_scheme
+
+ alias_method :show_drag_handle?, :show_drag_handle
# @param work_package [WorkPackage] the work package this card represents.
# @param menu_src [String, NilClass] optional lazy menu source. Prefer the
# `with_menu(src:)` slot for new call sites.
- def initialize(work_package:, menu_src: nil)
+ # @param show_drag_handle [Boolean] whether to show a drag handle icon.
+ # @param show_assignee [Boolean] whether to show the assignee (icon + name when space allows).
+ # @param show_priority [Boolean] whether to show the priority badge.
+ # @param show_parent [Boolean] whether to show a link to the parent work package in row 3.
+ # Only rendered when the work package actually has a parent.
+ # @param link_subject [Boolean] whether to link the subject to the WP or render as plain text instead.
+ # @param status_scheme [Symbol] status label scheme for the info line. One of :default or :secondary.
+ def initialize(work_package:, menu_src: nil, show_drag_handle: false,
+ show_assignee: false, show_priority: false, show_parent: false, link_subject: true,
+ status_scheme: :default)
super()
@work_package = work_package
@menu_src = menu_src
+ @show_drag_handle = show_drag_handle
+ @show_assignee = show_assignee
+ @show_priority = show_priority
+ @show_parent = show_parent
+ @link_subject = link_subject
+ @status_scheme = status_scheme
+ end
+
+ private
+
+ def layout_classes
+ {
+ "op-work-package-card_with-drag-handle": show_drag_handle?,
+ "op-work-package-card_with-footer": show_footer?,
+ "op-work-package-card_with-menu": menu? || menu_src.present?
+ }
+ end
+
+ def show_parent?
+ show_parent && work_package.parent&.visible?
+ end
+
+ def show_footer?
+ additional_details? || show_parent?
end
end
end
diff --git a/app/components/open_project/common/work_package_card_component.sass b/app/components/open_project/common/work_package_card_component.sass
index 8e79ba50667a..e468cbe08644 100644
--- a/app/components/open_project/common/work_package_card_component.sass
+++ b/app/components/open_project/common/work_package_card_component.sass
@@ -30,24 +30,74 @@
display: grid
grid-template-columns: 1fr auto
grid-template-rows: auto auto
- grid-template-areas: "info_line menu" "subject subject"
+ grid-template-areas: "info_line actions" "subject subject"
align-items: center
- margin-top: calc(-1 * var(--base-size-4))
+ grid-row-gap: var(--base-size-4)
+ margin-top: var(--base-size-4)
margin-bottom: var(--base-size-4)
+ container-type: inline-size
-.op-work-package-card_with-metric
- grid-template-columns: 1fr minmax(2rem, max-content) auto
- grid-template-areas: "info_line metric menu" "subject subject subject"
+ &_with-footer
+ grid-template-rows: auto auto auto
+ grid-template-areas: "info_line actions" "subject subject" "footer footer"
-.op-work-package-card--metric
- margin-left: var(--stack-gap-normal)
- font-variant-numeric: tabular-nums
- text-align: right
+ &_with-drag-handle
+ grid-template-columns: auto 1fr auto
+ grid-template-areas: "drag_handle info_line actions" ". subject subject"
-.op-work-package-card--menu
- margin-left: var(--stack-gap-normal)
+ &.op-work-package-card_with-footer
+ grid-template-rows: auto auto auto
+ grid-template-areas: "drag_handle info_line actions" ". subject subject" ". footer footer"
-.op-work-package-card--subject
- align-self: start // Align to top of second row
- word-wrap: break-word
- overflow-wrap: break-word
+ // --------- START: Menu positioning ---------
+ // This is a hack to avoid that the IconButton of the menu blows up the height of the first row
+ // resulting in different spacing between the rows.
+ // By positioning the menu absolutely, we can ensure that the height of the first row is not affected.
+ &_with-menu
+ .op-work-package-card--actions
+ position: relative
+ // 1rem column gap + 2rem button width - 0.5rem visual gap of the invisible button to it's icon
+ padding-right: 2.5rem
+
+ &--menu
+ position: absolute
+ right: 0
+ // --------- END: Menu positioning ---------
+
+ &--drag_handle
+ align-self: center
+ padding-right: var(--stack-gap-condensed)
+ cursor: grab
+ color: var(--fgColor-muted)
+
+ &--actions
+ display: flex
+ align-items: center
+ gap: var(--stack-gap-normal)
+ color: var(--fgColor-muted)
+
+ &--metric
+ font-variant-numeric: tabular-nums
+ text-align: right
+
+ // parent_link and additional_details auto-place into implicit rows, spanning full width
+ &--parent_link,
+ &--additional_details
+ grid-column: 1 / -1
+ padding-top: var(--base-size-4)
+
+ &_with-drag-handle
+ .op-work-package-card--parent_link,
+ .op-work-package-card--additional_details
+ grid-column: 2 / -1
+
+ &--subject
+ align-self: start
+ word-wrap: break-word
+ overflow-wrap: break-word
+
+ // < 768px: hide text labels, show only icons
+ @container (width < 768px)
+ .op-work-package-card--assignee-name,
+ .op-work-package-card--priority-name
+ display: none
diff --git a/app/components/open_project/common/work_package_card_component/menu.rb b/app/components/open_project/common/work_package_card_component/menu.rb
index 75568601d01b..faadab7e33cd 100644
--- a/app/components/open_project/common/work_package_card_component/menu.rb
+++ b/app/components/open_project/common/work_package_card_component/menu.rb
@@ -49,6 +49,7 @@ def initialize(work_package:, src: nil, button_aria_label: nil, **system_argumen
system_arguments[:anchor_align] ||= :end
system_arguments[:classes] = class_names(
system_arguments[:classes],
+ "op-work-package-card--menu",
"hide-when-print"
)
@menu = Primer::Alpha::ActionMenu.new(**system_arguments)
diff --git a/app/components/work_packages/info_line_component.html.erb b/app/components/work_packages/info_line_component.html.erb
index e4e05ec8bdf6..cf7a6e4ace9c 100644
--- a/app/components/work_packages/info_line_component.html.erb
+++ b/app/components/work_packages/info_line_component.html.erb
@@ -21,7 +21,7 @@
if @show_status
flex.with_column(ml: 2) do
- render WorkPackages::StatusBadgeComponent.new(status: @work_package.status)
+ render WorkPackages::StatusBadgeComponent.new(status: @work_package.status, scheme: @status_scheme)
end
end
diff --git a/app/components/work_packages/info_line_component.rb b/app/components/work_packages/info_line_component.rb
index 9be082a5acc2..e20b50b752fc 100644
--- a/app/components/work_packages/info_line_component.rb
+++ b/app/components/work_packages/info_line_component.rb
@@ -35,6 +35,7 @@ def initialize(work_package:,
show_project: false,
show_subject: false,
show_status: true,
+ status_scheme: :default,
font_size: :small,
**system_arguments)
super
@@ -44,6 +45,7 @@ def initialize(work_package:,
@show_project = show_project
@show_subject = show_subject
@show_status = show_status
+ @status_scheme = status_scheme
@system_arguments = system_arguments
end
diff --git a/app/components/work_packages/status_badge_component.rb b/app/components/work_packages/status_badge_component.rb
index 18462e3ee904..c388f8d03724 100644
--- a/app/components/work_packages/status_badge_component.rb
+++ b/app/components/work_packages/status_badge_component.rb
@@ -35,6 +35,13 @@ def initialize(status:, **system_arguments)
super
@status = status
- @system_arguments = system_arguments.merge({ classes: "__hl_background_status_#{@status.id}" })
+ @system_arguments = system_arguments
+ if @system_arguments[:scheme].nil? || @system_arguments[:scheme] == :default
+ @system_arguments.delete(:scheme)
+ @system_arguments[:classes] = class_names(
+ @system_arguments[:classes],
+ "__hl_background_status_#{@status.id}"
+ )
+ end
end
end
diff --git a/config/locales/en.yml b/config/locales/en.yml
index c725f5060d0c..482b3031d11b 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -4902,8 +4902,11 @@ en:
open_project:
common:
work_package_card_component:
+ drag_handle:
+ label: "Drag to reorder"
menu:
label_actions: "Work package actions"
+ parent: "Parent"
work_package_card_list_component:
header:
label_actions: "Open menu"
diff --git a/frontend/src/global_styles/layout/_colors.sass b/frontend/src/global_styles/layout/_colors.sass
index bad6dd16ef34..542043d27003 100644
--- a/frontend/src/global_styles/layout/_colors.sass
+++ b/frontend/src/global_styles/layout/_colors.sass
@@ -110,6 +110,11 @@
width: 10px
height: 10px
+ &.__hl_inline__small_dot:before
+ width: 6px
+ height: 6px
+ vertical-align: 1px
+
@mixin dot_border_width_style
[class^='__hl_inline_'],
[class*=' __hl_inline_']
diff --git a/lookbook/docs/components/work-packages/card.md.erb b/lookbook/docs/components/work-packages/card.md.erb
new file mode 100644
index 000000000000..77d68cd5f118
--- /dev/null
+++ b/lookbook/docs/components/work-packages/card.md.erb
@@ -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: true` and a parent exists) and/or the `with_additional_details` 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` | `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_additional_details` | 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: 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_additional_details do
+ # Whatever else you want to show
+ end
+end
+```
diff --git a/lookbook/previews/open_project/common/work_package_card_component_preview.rb b/lookbook/previews/open_project/common/work_package_card_component_preview.rb
index 0adc6dd1b50a..261e3b647db5 100644
--- a/lookbook/previews/open_project/common/work_package_card_component_preview.rb
+++ b/lookbook/previews/open_project/common/work_package_card_component_preview.rb
@@ -32,39 +32,103 @@ 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 toggle
+ # @param link_subject toggle
+ # @param show_metric toggle
+ # @param show_menu toggle
+ # @param additional_details toggle
+ # @param status_scheme select [default, secondary]
+ def playground(show_assignee: false, show_priority: false, show_drag_handle: false,
+ show_parent: false, link_subject: true, show_metric: false, show_menu: false,
+ additional_details: 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_subject:,
+ show_metric:,
+ show_menu:,
+ additional_details:,
+ 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:
- )
+ 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.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:
- ) do |card|
- card.with_metric_content(10)
+ 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.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:
- ) do |card|
+ 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:,
+ show_drag_handle: true
+ )
+ end
+
+ # Card with show_parent 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
+ 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:,
+ show_parent: true
+ )
+ end
+
+ # Card with additional content in the bottom slot (row 3), rendered alongside the parent link.
+ def with_additional_details
+ work_package = 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/with_additional_details",
+ locals: { work_package: })
+ end
+
private
def preview_message(text)
diff --git a/lookbook/previews/open_project/common/work_package_card_component_preview/playground.html.erb b/lookbook/previews/open_project/common/work_package_card_component_preview/playground.html.erb
new file mode 100644
index 000000000000..d255d25d7143
--- /dev/null
+++ b/lookbook/previews/open_project/common/work_package_card_component_preview/playground.html.erb
@@ -0,0 +1,26 @@
+<%= render OpenProject::Common::WorkPackageCardComponent.new(
+ work_package:,
+ show_assignee:,
+ show_priority:,
+ show_drag_handle:,
+ show_parent:,
+ link_subject:,
+ 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 additional_details
+ card.with_additional_details do
+ render(Primer::Beta::Text.new(tag: :span, font_size: :small, color: :subtle)) { "Some bottom line" }
+ end
+ end
+ end %>
diff --git a/lookbook/previews/open_project/common/work_package_card_component_preview/with_additional_details.html.erb b/lookbook/previews/open_project/common/work_package_card_component_preview/with_additional_details.html.erb
new file mode 100644
index 000000000000..cf567d83bc55
--- /dev/null
+++ b/lookbook/previews/open_project/common/work_package_card_component_preview/with_additional_details.html.erb
@@ -0,0 +1,5 @@
+<%= render OpenProject::Common::WorkPackageCardComponent.new(work_package:) do |card|
+ card.with_additional_details do
+ render(Primer::Beta::Text.new(tag: :span, font_size: :small, color: :subtle)) { "Some bottom line" }
+ end
+ end %>
diff --git a/lookbook/previews/open_project/work_packages/info_line_component_preview.rb b/lookbook/previews/open_project/work_packages/info_line_component_preview.rb
index 8331d308dccc..e579905ef6de 100644
--- a/lookbook/previews/open_project/work_packages/info_line_component_preview.rb
+++ b/lookbook/previews/open_project/work_packages/info_line_component_preview.rb
@@ -36,11 +36,13 @@ class InfoLineComponentPreview < ViewComponent::Preview
# @param show_subject [Boolean]
# @param show_status [Boolean]
# @param font_size [Symbol] select [small, normal]
- def playground(show_project: false, show_subject: false, show_status: true, font_size: :small)
+ # @param status_scheme select [default, secondary]
+ def playground(show_project: false, show_subject: false, show_status: true, font_size: :small, status_scheme: :default)
render(WorkPackages::InfoLineComponent.new(work_package: WorkPackage.visible.first,
show_project:,
show_subject:,
show_status:,
+ status_scheme:,
font_size:))
end
end
diff --git a/modules/backlogs/app/components/backlogs/sprint_component.rb b/modules/backlogs/app/components/backlogs/sprint_component.rb
index 2f89621b86db..6fe512292e12 100644
--- a/modules/backlogs/app/components/backlogs/sprint_component.rb
+++ b/modules/backlogs/app/components/backlogs/sprint_component.rb
@@ -46,7 +46,8 @@ def initialize(sprint:, project:, work_packages: nil, current_user: User.current
@project = project
@current_user = current_user
@active_sprint_ids = active_sprint_ids
- @work_packages = work_packages || sprint.work_packages_for(project).includes(:status, :type)
+ @work_packages = work_packages || sprint.work_packages_for(project).includes(:status, :type, :assigned_to, :priority,
+ :parent)
end
def wrapper_uniq_by
diff --git a/modules/backlogs/app/components/backlogs/work_package_card_component.rb b/modules/backlogs/app/components/backlogs/work_package_card_component.rb
index f0b69e46108b..16268a7a0563 100644
--- a/modules/backlogs/app/components/backlogs/work_package_card_component.rb
+++ b/modules/backlogs/app/components/backlogs/work_package_card_component.rb
@@ -54,7 +54,14 @@ def call
private
def card
- @card ||= OpenProject::Common::WorkPackageCardComponent.new(work_package:, menu_src:)
+ @card ||= OpenProject::Common::WorkPackageCardComponent.new(
+ work_package:,
+ menu_src:,
+ show_assignee: true,
+ show_priority: true,
+ show_parent: true,
+ status_scheme: :secondary
+ )
end
def before_render
diff --git a/modules/backlogs/app/controllers/backlogs/backlog_controller.rb b/modules/backlogs/app/controllers/backlogs/backlog_controller.rb
index 76e2183dd81c..e75051756138 100644
--- a/modules/backlogs/app/controllers/backlogs/backlog_controller.rb
+++ b/modules/backlogs/app/controllers/backlogs/backlog_controller.rb
@@ -73,7 +73,7 @@ def load_backlogs
@work_packages_by_sprint_id = WorkPackage
.where(sprint: @sprints, project: @project)
- .includes(:type, :status)
+ .includes(:type, :status, :assigned_to, :priority, :parent)
.order_by_position
.group_by(&:sprint_id)
@active_sprint_ids = @sprints.select(&:active?).map(&:id)
diff --git a/modules/backlogs/app/models/backlog_bucket.rb b/modules/backlogs/app/models/backlog_bucket.rb
index 3454697d0c61..0e8c7c003b18 100644
--- a/modules/backlogs/app/models/backlog_bucket.rb
+++ b/modules/backlogs/app/models/backlog_bucket.rb
@@ -43,6 +43,6 @@ class BacklogBucket < ApplicationRecord
validates :name, :project, presence: true
def self.for_project(project)
- where(project:).order_alphabetically.includes(:displayed_work_packages)
+ where(project:).order_alphabetically.includes(displayed_work_packages: %i[assigned_to priority parent])
end
end
diff --git a/modules/backlogs/app/models/work_packages/scopes/backlogs_inbox_for.rb b/modules/backlogs/app/models/work_packages/scopes/backlogs_inbox_for.rb
index 9a3aa68d9dee..925cb4fb23a0 100644
--- a/modules/backlogs/app/models/work_packages/scopes/backlogs_inbox_for.rb
+++ b/modules/backlogs/app/models/work_packages/scopes/backlogs_inbox_for.rb
@@ -37,7 +37,7 @@ def backlogs_inbox_for(project:)
.visible
.with_status_open
.where(project:, sprint_id: nil, backlog_bucket_id: nil)
- .includes(:type)
+ .includes(:type, :assigned_to, :priority, :parent)
.order_by_position
.order(WorkPackage.arel_table[:id].asc)
end