[#73909] add new view component structure

- https://community.openproject.org/work_packages/73909
- add new sections
- add new border boxes for all sections
- add collapsing logic
- add empty state for the whole tab
This commit is contained in:
Eric Schubert
2026-04-15 16:55:31 +02:00
parent d79261a58c
commit b3a14b74bf
9 changed files with 99 additions and 57 deletions
@@ -28,20 +28,16 @@ See COPYRIGHT and LICENSE files for more details.
++#%>
<%=
flex_layout do |container|
container.with_row(mb: 2) { render(Primer::Beta::Text.new(font_weight: :bold)) { t(".heading") } }
if page_links.empty?
container.with_row do
render(Primer::Beta::Blankslate.new(border: false)) do |blankslate|
blankslate.with_heading(tag: :h2).with_content(t(".empty_heading"))
blankslate.with_description { t(".empty_text") }
end
render(Primer::Beta::BorderBox.new(padding: :condensed)) do |box|
box.with_header do
render(Primer::OpenProject::BorderBox::CollapsibleHeader.new(collapsed: true)) do |header|
header.with_title { t(".heading") }
header.with_count(count: inline_page_links.count)
end
end
page_links.each do |page_link|
container.with_row(mt: 3) { render(Wikis::PageLinkComponent.new(page_link)) }
inline_page_links.each do |page_link|
box.with_row { render(Wikis::PageLinkComponent.new(page_link)) }
end
end
%>
@@ -33,21 +33,6 @@ module Wikis
include ApplicationHelper
include OpPrimer::ComponentHelpers
alias_method :provider, :model
def initialize(model = nil, work_package: nil, **)
@work_package = work_package
super(model, **)
end
def page_links
@page_links ||= page_link_service.inline_page_links_for(provider:, linkable: @work_package)
end
private
def page_link_service
@page_link_service ||= PageLinkService.new
end
alias_method :inline_page_links, :model
end
end
@@ -28,12 +28,16 @@ See COPYRIGHT and LICENSE files for more details.
++#%>
<%=
render(Primer::Beta::BorderBox.new) do |box|
render(Primer::Beta::BorderBox.new(padding: :condensed)) do |box|
box.with_header do
render(Primer::Beta::Text.new(font_weight: :bold)) { provider.name }
render(Primer::OpenProject::BorderBox::CollapsibleHeader.new(collapsed: true)) do |header|
header.with_title { t(".heading") }
header.with_count(count: referencing_page_links.count)
end
end
box.with_row { render(Wikis::RelationPageLinksComponent.new(provider, work_package: @work_package)) }
box.with_row { render(Wikis::InlinePageLinksComponent.new(provider, work_package: @work_package)) }
referencing_page_links.each do |page_link|
box.with_row { render(Wikis::PageLinkComponent.new(page_link)) }
end
end
%>
@@ -29,15 +29,10 @@
#++
module Wikis
class ProviderLinkGroupComponent < ApplicationComponent
class ReferencingPagesComponent < ApplicationComponent
include ApplicationHelper
include OpPrimer::ComponentHelpers
alias_method :provider, :model
def initialize(model = nil, work_package: nil, **)
@work_package = work_package
super(model, **)
end
alias_method :referencing_page_links, :model
end
end
@@ -28,11 +28,13 @@ See COPYRIGHT and LICENSE files for more details.
++#%>
<%=
flex_layout do |container|
container.with_row(mb: 2) do
flex_layout(justify_content: :space_between, align_items: :center) do |header|
header.with_column { render(Primer::Beta::Text.new(font_weight: :bold)) { t(".heading") } }
render(Primer::Beta::BorderBox.new(padding: :condensed)) do |box|
box.with_header do
flex_layout(align_items: :center, justify_content: :space_between) do |header|
header.with_column do
concat(render(Primer::Beta::Text.new(font_weight: :bold, mr: 2)) { provider.name })
concat(render(Primer::Beta::Counter.new(count: page_links.count, round: true, scheme: :primary)))
end
header.with_column do
render(Primer::Alpha::ActionMenu.new) do |menu|
menu.with_show_button(disabled: true) do |button|
@@ -49,7 +51,7 @@ See COPYRIGHT and LICENSE files for more details.
end
if page_links.empty?
container.with_row do
box.with_row do
render(Primer::Beta::Blankslate.new(border: false)) do |blankslate|
blankslate.with_heading(tag: :h2).with_content(t(".empty_heading"))
blankslate.with_description { t(".empty_text") }
@@ -58,7 +60,7 @@ See COPYRIGHT and LICENSE files for more details.
end
page_links.each do |page_link|
container.with_row(mt: 3) { render(Wikis::PageLinkComponent.new(page_link)) }
box.with_row { render(Wikis::PageLinkComponent.new(page_link)) }
end
end
%>
@@ -30,10 +30,41 @@ See COPYRIGHT and LICENSE files for more details.
<%=
content_tag("turbo-frame", id: "work-package-wikis-tab-content") do
component_wrapper do
flex_layout(test_selector: "op-work-package-wikis-tab-container") do |flex|
providers.each do |provider|
flex.with_row(mb: 3) do
render(Wikis::ProviderLinkGroupComponent.new(provider, work_package:))
flex_layout(test_selector: "op-work-package-wikis-tab-container") do |container|
if providers.empty?
container.with_row do
render(Primer::Beta::Blankslate.new(border: false)) do |blankslate|
blankslate.with_heading(tag: :h2).with_content(t(".blankslate.heading"))
blankslate.with_description { t(".blankslate.description") }
end
end
else
container.with_row do
render(Primer::Beta::Heading.new(tag: :h4, mb: 3)) { t(".relation_page_links") }
end
providers.each do |provider|
container.with_row(mb: 3) do
render(::Wikis::RelationPageLinksComponent.new(provider, work_package:))
end
end
if show_inline_and_references_section?
container.with_row(mb: 3) do
render(Primer::Beta::Heading.new(tag: :h4)) { t(".inline_page_links_and_references") }
end
end
if inline_page_links.any?
container.with_row(mb: 3) do
render(::Wikis::InlinePageLinksComponent.new(inline_page_links))
end
end
if referencing_wiki_pages.any?
container.with_row(mb: 3) do
render(::Wikis::ReferencingPagesComponent.new(referencing_wiki_pages))
end
end
end
end
@@ -39,5 +39,23 @@ module Wikis
def providers
Wikis::Provider.enabled
end
def show_inline_and_references_section?
inline_page_links.any? || referencing_wiki_pages.any?
end
def inline_page_links
@inline_page_links ||= page_link_service.inline_page_links_for(linkable: work_package)
end
def referencing_wiki_pages
@referencing_wiki_pages ||= page_link_service.referencing_wiki_pages_for(linkable: work_package)
end
private
def page_link_service
@page_link_service ||= PageLinkService.new
end
end
end
@@ -48,11 +48,15 @@ module Wikis
.order(created_at: :desc)
end
def inline_page_links_for(provider:, linkable:)
provider.page_links
.merge(InlinePageLink.all)
.where(linkable:)
.order(created_at: :desc)
def inline_page_links_for(linkable:)
InlinePageLink.where(linkable:)
.order(created_at: :desc)
end
def referencing_wiki_pages_for(*)
# TODO: iterate over all providers and fetch mentions of this linkable
[]
end
end
end
+10 -3
View File
@@ -27,16 +27,23 @@ en:
buttons:
save_and_continue: Save and continue
wiki_page: Wiki page
work_package_wikis_tab_component:
relation_page_links: Related pages
inline_page_links_and_references: Inline page links and references
blankslate:
heading: No wiki providers enabled
description: >-
There are no wiki providers configured and enabled. Wiki page links can only be added for enabled providers.
To add wiki providers, visit Administration > Wikis.
inline_page_links_component:
empty_heading: No inline links
empty_text: Inline links to wiki pages in the work package description will automatically also show up here.
heading: Inline page links
referencing_pages_component:
heading: Referenced in
page_link_component:
remove: Remove page link
relation_page_links_component:
empty_heading: No related pages
empty_text: Manually add links to other related wiki pages.
heading: Related pages
admin:
wiki_providers:
index_description: Add an external wiki service to link work packages to existing wiki pages or create new ones directly from OpenProject.