From 348fdac823a06f1b7c66106910c33c8d5985e7a0 Mon Sep 17 00:00:00 2001 From: Henriette Darge Date: Wed, 2 Oct 2024 15:06:11 +0200 Subject: [PATCH] Rename "wpPreviewModal" to a more generic "hoverCard" and use a turboFrame inside to be more flexible about the content --- .../work_packages/hover_card_controller.rb | 37 ++++++++++ app/helpers/work_packages_helper.rb | 2 +- .../work_packages/hover_card/show.html.erb | 3 + config/initializers/permissions.rb | 3 +- config/routes.rb | 2 + frontend/src/app/app.module.ts | 10 +-- ...rvice.ts => hover-card-trigger.service.ts} | 32 +++------ .../macros/work-package-quickinfo-macro.html | 2 +- .../hover-card-modal/hover-card.modal.html | 17 +++++ .../hover-card-modal/hover-card.modal.sass | 10 +++ .../hover-card.modal.ts} | 70 ++++++++----------- .../wp-preview-modal/wp-preview.modal.html | 10 --- .../wp-preview-modal/wp-preview.modal.sass | 9 --- .../text_formatting/filters/mention_filter.rb | 2 +- .../matchers/link_handlers/work_packages.rb | 2 +- .../markdown/activity_comments_spec.rb | 2 +- .../wysiwyg/macros/quicklink_macros_spec.rb | 6 +- .../repositories/revision_representer_spec.rb | 2 +- .../markdown/in_tool_links_spec.rb | 6 +- spec/requests/api/v3/render_resource_spec.rb | 4 +- 20 files changed, 128 insertions(+), 103 deletions(-) create mode 100644 app/controllers/work_packages/hover_card_controller.rb create mode 100644 app/views/work_packages/hover_card/show.html.erb rename frontend/src/app/core/setup/globals/global-listeners/{preview-trigger.service.ts => hover-card-trigger.service.ts} (67%) create mode 100644 frontend/src/app/shared/components/modals/preview-modal/hover-card-modal/hover-card.modal.html create mode 100644 frontend/src/app/shared/components/modals/preview-modal/hover-card-modal/hover-card.modal.sass rename frontend/src/app/shared/components/modals/preview-modal/{wp-preview-modal/wp-preview.modal.ts => hover-card-modal/hover-card.modal.ts} (59%) delete mode 100644 frontend/src/app/shared/components/modals/preview-modal/wp-preview-modal/wp-preview.modal.html delete mode 100644 frontend/src/app/shared/components/modals/preview-modal/wp-preview-modal/wp-preview.modal.sass diff --git a/app/controllers/work_packages/hover_card_controller.rb b/app/controllers/work_packages/hover_card_controller.rb new file mode 100644 index 00000000000..7979c7821fd --- /dev/null +++ b/app/controllers/work_packages/hover_card_controller.rb @@ -0,0 +1,37 @@ +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) the OpenProject GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2013 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See COPYRIGHT and LICENSE files for more details. +#++ +module WorkPackages + class HoverCardController < ApplicationController + before_action :load_and_authorize_in_optional_project + + def show + @id = params[:id] + render layout: nil + end + end +end diff --git a/app/helpers/work_packages_helper.rb b/app/helpers/work_packages_helper.rb index 8e237f03638..eb320e18141 100644 --- a/app/helpers/work_packages_helper.rb +++ b/app/helpers/work_packages_helper.rb @@ -173,7 +173,7 @@ module WorkPackagesHelper # Returns a string of css classes that apply to the issue def work_package_css_classes(work_package) - s = "work_package preview-trigger".html_safe + s = "work_package op-hover-card--preview-trigger".html_safe s << " status-#{work_package.status.position}" if work_package.status s << " priority-#{work_package.priority.position}" if work_package.priority s << " closed" if work_package.closed? diff --git a/app/views/work_packages/hover_card/show.html.erb b/app/views/work_packages/hover_card/show.html.erb new file mode 100644 index 00000000000..8385b69e31d --- /dev/null +++ b/app/views/work_packages/hover_card/show.html.erb @@ -0,0 +1,3 @@ + + Hallo WELT + diff --git a/config/initializers/permissions.rb b/config/initializers/permissions.rb index d0ea7360287..a47ee9006cd 100644 --- a/config/initializers/permissions.rb +++ b/config/initializers/permissions.rb @@ -217,7 +217,8 @@ Rails.application.reloader.to_prepare do work_packages: %i[show index], work_packages_api: [:get], "work_packages/reports": %i[report report_details], - "work_packages/menus": %i[show] + "work_packages/menus": %i[show], + "work_packages/hover_card": %i[show] }, permissible_on: %i[work_package project], contract_actions: { work_packages: %i[read] } diff --git a/config/routes.rb b/config/routes.rb index 0eaec67895d..63631830755 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -571,6 +571,8 @@ Rails.application.routes.draw do resources :work_packages, only: [:index] do concerns :shareable + get "hover_card" => "work_packages/hover_card#show", on: :member + # move bulk of wps get "move/new" => "work_packages/moves#new", on: :collection, as: "new_move" post "move" => "work_packages/moves#create", on: :collection, as: "move" diff --git a/frontend/src/app/app.module.ts b/frontend/src/app/app.module.ts index f8d39a6f527..a35922776ad 100644 --- a/frontend/src/app/app.module.ts +++ b/frontend/src/app/app.module.ts @@ -53,7 +53,7 @@ import { OpenprojectDashboardsModule } from 'core-app/features/dashboards/openpr import { OpenprojectWorkPackageGraphsModule, } from 'core-app/shared/components/work-package-graphs/openproject-work-package-graphs.module'; -import { PreviewTriggerService } from 'core-app/core/setup/globals/global-listeners/preview-trigger.service'; +import { HoverCardTriggerService } from 'core-app/core/setup/globals/global-listeners/hover-card-trigger.service'; import { OpenprojectOverviewModule } from 'core-app/features/overview/openproject-overview.module'; import { OpenprojectMyPageModule } from 'core-app/features/my-page/openproject-my-page.module'; import { OpenprojectProjectsModule } from 'core-app/features/projects/openproject-projects.module'; @@ -77,8 +77,8 @@ import { PasswordConfirmationModalComponent, } from 'core-app/shared/components/modals/request-for-confirmation/password-confirmation.modal'; import { - WpPreviewModalComponent, -} from 'core-app/shared/components/modals/preview-modal/wp-preview-modal/wp-preview.modal'; + HoverCardComponent, +} from 'core-app/shared/components/modals/preview-modal/hover-card-modal/hover-card.modal'; import { OpHeaderProjectSelectComponent, } from 'core-app/shared/components/header-project-select/header-project-select.component'; @@ -240,7 +240,7 @@ import { SpotSwitchComponent } from 'core-app/spot/components/switch/switch.comp export function initializeServices(injector:Injector) { return () => { - const PreviewTrigger = injector.get(PreviewTriggerService); + const PreviewTrigger = injector.get(HoverCardTriggerService); const topMenuService = injector.get(TopMenuService); const keyboardShortcuts = injector.get(KeyboardShortcutService); // Conditionally add the Revit Add-In settings button @@ -370,7 +370,7 @@ export function initializeServices(injector:Injector) { ConfirmDialogModalComponent, DynamicContentModalComponent, PasswordConfirmationModalComponent, - WpPreviewModalComponent, + HoverCardComponent, // Main menu MainMenuResizerComponent, diff --git a/frontend/src/app/core/setup/globals/global-listeners/preview-trigger.service.ts b/frontend/src/app/core/setup/globals/global-listeners/hover-card-trigger.service.ts similarity index 67% rename from frontend/src/app/core/setup/globals/global-listeners/preview-trigger.service.ts rename to frontend/src/app/core/setup/globals/global-listeners/hover-card-trigger.service.ts index 239f5e5dabe..8787b1304f8 100644 --- a/frontend/src/app/core/setup/globals/global-listeners/preview-trigger.service.ts +++ b/frontend/src/app/core/setup/globals/global-listeners/hover-card-trigger.service.ts @@ -28,10 +28,10 @@ import { Injectable, Injector, NgZone } from '@angular/core'; import { OpModalService } from 'core-app/shared/components/modal/modal.service'; -import { WpPreviewModalComponent } from 'core-app/shared/components/modals/preview-modal/wp-preview-modal/wp-preview.modal'; +import { HoverCardComponent } from 'core-app/shared/components/modals/preview-modal/hover-card-modal/hover-card.modal'; @Injectable({ providedIn: 'root' }) -export class PreviewTriggerService { +export class HoverCardTriggerService { private modalElement:HTMLElement; private mouseInModal = false; @@ -44,7 +44,7 @@ export class PreviewTriggerService { } setupListener() { - jQuery(document.body).on('mouseover', '.preview-trigger', (e) => { + jQuery(document.body).on('mouseover', '.op-hover-card--preview-trigger', (e) => { e.preventDefault(); e.stopPropagation(); // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment @@ -58,8 +58,9 @@ export class PreviewTriggerService { } this.opModalService.show( - WpPreviewModalComponent, + HoverCardComponent, this.injector, + // TODO { workPackageLink: href, event: e }, true, ).subscribe((previewModal) => { @@ -69,16 +70,16 @@ export class PreviewTriggerService { } }); - jQuery(document.body).on('mouseleave', '.preview-trigger', () => { + jQuery(document.body).on('mouseleave', '.op-hover-card--preview-trigger', () => { this.closeAfterTimeout(); }); - jQuery(document.body).on('mouseleave', '.op-wp-preview-modal', () => { + jQuery(document.body).on('mouseleave', '.op-hover-card', () => { this.mouseInModal = false; this.closeAfterTimeout(); }); - jQuery(document.body).on('mouseenter', '.op-wp-preview-modal', () => { + jQuery(document.body).on('mouseenter', '.op-hover-card', () => { this.mouseInModal = true; }); } @@ -92,21 +93,4 @@ export class PreviewTriggerService { }, 100); }); } - - private isMouseOverPreview(e:JQuery.MouseLeaveEvent) { - if (!this.modalElement) { - return false; - } - - const previewElement = jQuery(this.modalElement.children[0]); - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - if (previewElement && previewElement.offset()) { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const horizontalHover = e.pageX >= Math.floor(previewElement.offset()!.left) && e.pageX < previewElement.offset()!.left + previewElement.width()!; - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const verticalHover = e.pageY >= Math.floor(previewElement.offset()!.top) && e.pageY < previewElement.offset()!.top + previewElement.height()!; - return horizontalHover && verticalHover; - } - return false; - } } diff --git a/frontend/src/app/shared/components/fields/macros/work-package-quickinfo-macro.html b/frontend/src/app/shared/components/fields/macros/work-package-quickinfo-macro.html index 5715653d381..d652b451622 100644 --- a/frontend/src/app/shared/components/fields/macros/work-package-quickinfo-macro.html +++ b/frontend/src/app/shared/components/fields/macros/work-package-quickinfo-macro.html @@ -9,7 +9,7 @@ [displayFieldOptions]="{ writable: false }" fieldName="type"> - diff --git a/frontend/src/app/shared/components/modals/preview-modal/hover-card-modal/hover-card.modal.html b/frontend/src/app/shared/components/modals/preview-modal/hover-card-modal/hover-card.modal.html new file mode 100644 index 00000000000..0143d9427fc --- /dev/null +++ b/frontend/src/app/shared/components/modals/preview-modal/hover-card-modal/hover-card.modal.html @@ -0,0 +1,17 @@ +
+ + + + + + + +
diff --git a/frontend/src/app/shared/components/modals/preview-modal/hover-card-modal/hover-card.modal.sass b/frontend/src/app/shared/components/modals/preview-modal/hover-card-modal/hover-card.modal.sass new file mode 100644 index 00000000000..ca901fb7c05 --- /dev/null +++ b/frontend/src/app/shared/components/modals/preview-modal/hover-card-modal/hover-card.modal.sass @@ -0,0 +1,10 @@ +@import "helpers" + +.op-hover-card + position: absolute + background-color: var(--body-background) + z-index: 5000 + min-width: 350px + box-shadow: var(--shadow-floating-large) + pointer-events: all + padding: 1rem diff --git a/frontend/src/app/shared/components/modals/preview-modal/wp-preview-modal/wp-preview.modal.ts b/frontend/src/app/shared/components/modals/preview-modal/hover-card-modal/hover-card.modal.ts similarity index 59% rename from frontend/src/app/shared/components/modals/preview-modal/wp-preview-modal/wp-preview.modal.ts rename to frontend/src/app/shared/components/modals/preview-modal/hover-card-modal/hover-card.modal.ts index a5ebb78b1c0..e29089da21b 100644 --- a/frontend/src/app/shared/components/modals/preview-modal/wp-preview-modal/wp-preview.modal.ts +++ b/frontend/src/app/shared/components/modals/preview-modal/hover-card-modal/hover-card.modal.ts @@ -32,17 +32,12 @@ import { Component, ElementRef, Inject, - OnInit, Input, + OnInit, } from '@angular/core'; import { OpModalComponent } from 'core-app/shared/components/modal/modal.component'; -import { OpModalLocalsToken, OpModalService } from 'core-app/shared/components/modal/modal.service'; +import { OpModalLocalsToken } from 'core-app/shared/components/modal/modal.service'; import { OpModalLocalsMap } from 'core-app/shared/components/modal/modal.types'; -import { I18nService } from 'core-app/core/i18n/i18n.service'; -import { WorkPackageResource } from 'core-app/features/hal/resources/work-package-resource'; -import idFromLink from 'core-app/features/hal/helpers/id-from-link'; -import { ApiV3Service } from 'core-app/core/apiv3/api-v3.service'; -import { StateService } from '@uirouter/core'; import { computePosition, flip, @@ -50,57 +45,57 @@ import { Placement, shift, } from '@floating-ui/dom'; +import { WorkPackageIsolatedQuerySpaceDirective } from 'core-app/features/work-packages/directives/query-space/wp-isolated-query-space.directive'; +import { fromEvent } from 'rxjs'; import { - WorkPackageIsolatedQuerySpaceDirective, -} from 'core-app/features/work-packages/directives/query-space/wp-isolated-query-space.directive'; + filter, + tap, + throttleTime, +} from 'rxjs/operators'; @Component({ - templateUrl: './wp-preview.modal.html', - styleUrls: ['./wp-preview.modal.sass'], + templateUrl: './hover-card.modal.html', + styleUrls: ['./hover-card.modal.sass'], changeDetection: ChangeDetectionStrategy.OnPush, hostDirectives: [WorkPackageIsolatedQuerySpaceDirective], }) -export class WpPreviewModalComponent extends OpModalComponent implements OnInit { - public workPackage:WorkPackageResource; - - public text = { - created_by: this.i18n.t('js.label_created_by'), - }; +export class HoverCardComponent extends OpModalComponent implements OnInit { + @Input() public turboFrameSrc:string = "/work_packages/50/hover_card"; @Input() public alignment?:Placement = 'bottom-end'; @Input() public allowRepositioning? = true; + public test:string; + constructor( readonly elementRef:ElementRef, @Inject(OpModalLocalsToken) readonly locals:OpModalLocalsMap, readonly cdRef:ChangeDetectorRef, - readonly i18n:I18nService, - readonly apiV3Service:ApiV3Service, - readonly opModalService:OpModalService, - readonly $state:StateService, ) { super(locals, cdRef, elementRef); } ngOnInit() { super.ngOnInit(); - const { workPackageLink } = this.locals; - const workPackageId = idFromLink(workPackageLink as string|null); - this - .apiV3Service - .work_packages - .id(workPackageId) - .requireAndStream() - .subscribe((workPackage:WorkPackageResource) => { - this.workPackage = workPackage; - this.cdRef.detectChanges(); + this.test = this.turboFrameSrc; - const modal = this.elementRef.nativeElement as HTMLElement; - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-explicit-any - void this.reposition(modal, this.locals.event.target as HTMLElement); - }); + // TODO + fromEvent(document, 'turbo:frame-load') + .pipe( + filter((event:CustomEvent) => { + return (event.target as HTMLElement).id?.includes('op-hover-card-body'); + }), + throttleTime(100), + tap(() => { + this.cdRef.detectChanges(); + + const modal = this.elementRef.nativeElement as HTMLElement; + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-explicit-any + void this.reposition(modal, this.locals.event.target as HTMLElement); + }), + ); } public async reposition(element:HTMLElement, target:HTMLElement) { @@ -125,9 +120,4 @@ export class WpPreviewModalComponent extends OpModalComponent implements OnInit top: `${y}px`, }); } - - public openStateLink(event:{ workPackageId:string; requestedState:string }) { - const params = { workPackageId: event.workPackageId }; - void this.$state.go(event.requestedState, params); - } } diff --git a/frontend/src/app/shared/components/modals/preview-modal/wp-preview-modal/wp-preview.modal.html b/frontend/src/app/shared/components/modals/preview-modal/wp-preview-modal/wp-preview.modal.html deleted file mode 100644 index f87dd3384d3..00000000000 --- a/frontend/src/app/shared/components/modals/preview-modal/wp-preview-modal/wp-preview.modal.html +++ /dev/null @@ -1,10 +0,0 @@ -
- -
diff --git a/frontend/src/app/shared/components/modals/preview-modal/wp-preview-modal/wp-preview.modal.sass b/frontend/src/app/shared/components/modals/preview-modal/wp-preview-modal/wp-preview.modal.sass deleted file mode 100644 index 2ceae2dfb05..00000000000 --- a/frontend/src/app/shared/components/modals/preview-modal/wp-preview-modal/wp-preview.modal.sass +++ /dev/null @@ -1,9 +0,0 @@ -@import "helpers" - -.op-wp-preview-modal - position: absolute - z-index: 5000 - min-width: 350px - padding: 0px - box-shadow: 0px 0px 5px 2px rgba(0, 0, 0, 0.25) - pointer-events: all \ No newline at end of file diff --git a/lib/open_project/text_formatting/filters/mention_filter.rb b/lib/open_project/text_formatting/filters/mention_filter.rb index f007d464ea0..4b7ac6a2bd9 100644 --- a/lib/open_project/text_formatting/filters/mention_filter.rb +++ b/lib/open_project/text_formatting/filters/mention_filter.rb @@ -75,7 +75,7 @@ module OpenProject::TextFormatting def work_package_mention(work_package) link_to("##{work_package.id}", work_package_path_or_url(id: work_package.id, only_path: context[:only_path]), - class: "issue work_package preview-trigger") + class: "issue work_package op-hover-card--preview-trigger") end def class_from_mention(mention) diff --git a/lib/open_project/text_formatting/matchers/link_handlers/work_packages.rb b/lib/open_project/text_formatting/matchers/link_handlers/work_packages.rb index dfffcf173db..4b2fd7bff2e 100644 --- a/lib/open_project/text_formatting/matchers/link_handlers/work_packages.rb +++ b/lib/open_project/text_formatting/matchers/link_handlers/work_packages.rb @@ -66,7 +66,7 @@ module OpenProject::TextFormatting::Matchers def render_work_package_link(wp_id) link_to("##{wp_id}", work_package_path_or_url(id: wp_id, only_path: context[:only_path]), - class: "issue work_package preview-trigger") + class: "issue work_package op-hover-card--preview-trigger") end end end diff --git a/spec/features/work_packages/details/markdown/activity_comments_spec.rb b/spec/features/work_packages/details/markdown/activity_comments_spec.rb index 06ba11d9d6e..3ceed0353dd 100644 --- a/spec/features/work_packages/details/markdown/activity_comments_spec.rb +++ b/spec/features/work_packages/details/markdown/activity_comments_spec.rb @@ -247,7 +247,7 @@ RSpec.describe "activity comments", :js do wp_page.expect_comment text: "Single ##{work_package2.id}" expect(page).to have_css(".user-comment opce-macro-wp-quickinfo", count: 2) - expect(page).to have_css(".user-comment .work-package--quickinfo.preview-trigger", count: 2) + expect(page).to have_css(".user-comment .op-hover-card--preview-trigger", count: 2) end end diff --git a/spec/features/wysiwyg/macros/quicklink_macros_spec.rb b/spec/features/wysiwyg/macros/quicklink_macros_spec.rb index d487d2ad5e1..40ebe4d116f 100644 --- a/spec/features/wysiwyg/macros/quicklink_macros_spec.rb +++ b/spec/features/wysiwyg/macros/quicklink_macros_spec.rb @@ -55,7 +55,7 @@ RSpec.describe "Wysiwyg work package quicklink macros", :js do # Expect output widget within("#content") do expect(page).to have_link("##{work_package.id}") - expect(page).to have_no_css(".work-package--quickinfo.preview-trigger") + expect(page).to have_no_css(".op-hover-card--preview-trigger") end # Edit page again @@ -77,7 +77,7 @@ RSpec.describe "Wysiwyg work package quicklink macros", :js do expected_macro_text = "#{work_package.type.name.upcase} ##{work_package.id}: My subject" expect(page).to have_css("opce-macro-wp-quickinfo", text: expected_macro_text) expect(page).to have_css("span", text: work_package.type.name.upcase) - expect(page).to have_css(".work-package--quickinfo.preview-trigger", text: "##{work_package.id}") + expect(page).to have_css(".op-hover-card--preview-trigger", text: "##{work_package.id}") expect(page).to have_css("span", text: "My subject") end @@ -102,7 +102,7 @@ RSpec.describe "Wysiwyg work package quicklink macros", :js do expect(page).to have_css("opce-macro-wp-quickinfo", text: expected_macro_text) expect(page).to have_css("span", text: work_package.status.name) expect(page).to have_css("span", text: work_package.type.name.upcase) - expect(page).to have_css(".work-package--quickinfo.preview-trigger", text: "##{work_package.id}") + expect(page).to have_css(".op-hover-card--preview-trigger", text: "##{work_package.id}") expect(page).to have_css("span", text: "My subject") # Dates are being rendered in two nested spans expect(page).to have_css("span", text: "01/01/2020", count: 2) diff --git a/spec/lib/api/v3/repositories/revision_representer_spec.rb b/spec/lib/api/v3/repositories/revision_representer_spec.rb index 13ce2f9b2b7..24e90c30c07 100644 --- a/spec/lib/api/v3/repositories/revision_representer_spec.rb +++ b/spec/lib/api/v3/repositories/revision_representer_spec.rb @@ -95,7 +95,7 @@ RSpec.describe API::V3::Repositories::RevisionRepresenter do id = work_package.id str = "Totally references " str << "##{id}
" end diff --git a/spec/lib/open_project/text_formatting/markdown/in_tool_links_spec.rb b/spec/lib/open_project/text_formatting/markdown/in_tool_links_spec.rb index 22968a58013..94cb8580fb8 100644 --- a/spec/lib/open_project/text_formatting/markdown/in_tool_links_spec.rb +++ b/spec/lib/open_project/text_formatting/markdown/in_tool_links_spec.rb @@ -267,7 +267,7 @@ RSpec.describe OpenProject::TextFormatting, let(:work_package_link) do link_to("##{work_package.id}", work_package_path(work_package), - class: "issue work_package preview-trigger op-uc-link", + class: "issue work_package op-hover-card--preview-trigger op-uc-link", target: "_top") end @@ -337,7 +337,7 @@ RSpec.describe OpenProject::TextFormatting, let(:work_package_link) do link_to("##{work_package.id}", work_package_path(work_package), - class: "issue work_package preview-trigger op-uc-link", + class: "issue work_package op-hover-card--preview-trigger op-uc-link", target: "_top") end @@ -656,7 +656,7 @@ RSpec.describe OpenProject::TextFormatting, let(:expected) do <<~EXPECTED

CookBook documentation

-

##{work_package.id}

+

##{work_package.id}

           [[CookBook documentation]]
 
diff --git a/spec/requests/api/v3/render_resource_spec.rb b/spec/requests/api/v3/render_resource_spec.rb
index c66def7ce8e..bf8a8e6f38f 100644
--- a/spec/requests/api/v3/render_resource_spec.rb
+++ b/spec/requests/api/v3/render_resource_spec.rb
@@ -90,7 +90,7 @@ RSpec.describe "API v3 Render resource" do
               <<~HTML
                 

Hello World! Have a look at - ##{id}

@@ -180,7 +180,7 @@ RSpec.describe "API v3 Render resource" do it_behaves_like "valid response" do let(:text) do - "

Hello *World*! Have a look at #1

\n\n

with two lines.

" + "

Hello *World*! Have a look at #1

\n\n

with two lines.

" end end end