From b3a14b74bf8af3e3f158e8700299cdcbd445f7ae Mon Sep 17 00:00:00 2001 From: Eric Schubert Date: Wed, 15 Apr 2026 16:55:31 +0200 Subject: [PATCH] [#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 --- .../inline_page_links_component.html.erb | 18 ++++----- .../wikis/inline_page_links_component.rb | 17 +------- ...b => referencing_pages_component.html.erb} | 12 ++++-- ...nent.rb => referencing_pages_component.rb} | 9 +---- .../relation_page_links_component.html.erb | 16 ++++---- .../work_package_wikis_tab_component.html.erb | 39 +++++++++++++++++-- .../wikis/work_package_wikis_tab_component.rb | 18 +++++++++ .../app/services/wikis/page_link_service.rb | 14 ++++--- modules/wikis/config/locales/en.yml | 13 +++++-- 9 files changed, 99 insertions(+), 57 deletions(-) rename modules/wikis/app/components/wikis/{provider_link_group_component.html.erb => referencing_pages_component.html.erb} (74%) rename modules/wikis/app/components/wikis/{provider_link_group_component.rb => referencing_pages_component.rb} (86%) diff --git a/modules/wikis/app/components/wikis/inline_page_links_component.html.erb b/modules/wikis/app/components/wikis/inline_page_links_component.html.erb index 88b539035c6..8c21bb36055 100644 --- a/modules/wikis/app/components/wikis/inline_page_links_component.html.erb +++ b/modules/wikis/app/components/wikis/inline_page_links_component.html.erb @@ -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 %> diff --git a/modules/wikis/app/components/wikis/inline_page_links_component.rb b/modules/wikis/app/components/wikis/inline_page_links_component.rb index cc3c7e44407..2776668a07e 100644 --- a/modules/wikis/app/components/wikis/inline_page_links_component.rb +++ b/modules/wikis/app/components/wikis/inline_page_links_component.rb @@ -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 diff --git a/modules/wikis/app/components/wikis/provider_link_group_component.html.erb b/modules/wikis/app/components/wikis/referencing_pages_component.html.erb similarity index 74% rename from modules/wikis/app/components/wikis/provider_link_group_component.html.erb rename to modules/wikis/app/components/wikis/referencing_pages_component.html.erb index 8f6fb847895..f1be4032537 100644 --- a/modules/wikis/app/components/wikis/provider_link_group_component.html.erb +++ b/modules/wikis/app/components/wikis/referencing_pages_component.html.erb @@ -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 %> diff --git a/modules/wikis/app/components/wikis/provider_link_group_component.rb b/modules/wikis/app/components/wikis/referencing_pages_component.rb similarity index 86% rename from modules/wikis/app/components/wikis/provider_link_group_component.rb rename to modules/wikis/app/components/wikis/referencing_pages_component.rb index bb99600b8e0..0e494f1d10f 100644 --- a/modules/wikis/app/components/wikis/provider_link_group_component.rb +++ b/modules/wikis/app/components/wikis/referencing_pages_component.rb @@ -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 diff --git a/modules/wikis/app/components/wikis/relation_page_links_component.html.erb b/modules/wikis/app/components/wikis/relation_page_links_component.html.erb index ba7a0d0b9f0..ad2989ce32b 100644 --- a/modules/wikis/app/components/wikis/relation_page_links_component.html.erb +++ b/modules/wikis/app/components/wikis/relation_page_links_component.html.erb @@ -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 %> diff --git a/modules/wikis/app/components/wikis/work_package_wikis_tab_component.html.erb b/modules/wikis/app/components/wikis/work_package_wikis_tab_component.html.erb index 01814295be3..31ac1bead97 100644 --- a/modules/wikis/app/components/wikis/work_package_wikis_tab_component.html.erb +++ b/modules/wikis/app/components/wikis/work_package_wikis_tab_component.html.erb @@ -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 diff --git a/modules/wikis/app/components/wikis/work_package_wikis_tab_component.rb b/modules/wikis/app/components/wikis/work_package_wikis_tab_component.rb index 254a45684e9..182dd48a75e 100644 --- a/modules/wikis/app/components/wikis/work_package_wikis_tab_component.rb +++ b/modules/wikis/app/components/wikis/work_package_wikis_tab_component.rb @@ -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 diff --git a/modules/wikis/app/services/wikis/page_link_service.rb b/modules/wikis/app/services/wikis/page_link_service.rb index edf3a234c17..3f58978019c 100644 --- a/modules/wikis/app/services/wikis/page_link_service.rb +++ b/modules/wikis/app/services/wikis/page_link_service.rb @@ -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 diff --git a/modules/wikis/config/locales/en.yml b/modules/wikis/config/locales/en.yml index 3ebdc90b179..af2a3a8eb40 100644 --- a/modules/wikis/config/locales/en.yml +++ b/modules/wikis/config/locales/en.yml @@ -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.