mirror of
https://github.com/opf/openproject.git
synced 2026-06-14 03:30:14 +00:00
Merge pull request #23311 from opf/implementation/75165-show-error-states-in-page-link-component
[#75165] show error states in the page link component
This commit is contained in:
@@ -29,14 +29,14 @@ See COPYRIGHT and LICENSE files for more details.
|
||||
|
||||
<%=
|
||||
render(OpPrimer::InlineMacroComponent.new) do |inline_macro|
|
||||
inline_macro.with_leading_visual_icon(icon: :"op-file-doc")
|
||||
|
||||
page_info_result.either(
|
||||
->(page_info) do
|
||||
inline_macro.with_leading_visual_icon(icon: :"op-file-doc")
|
||||
render(Primer::Beta::Link.new(href: page_info.href)) { page_info.title }
|
||||
end,
|
||||
->(_error) do
|
||||
render(Primer::Beta::Text.new(color: :muted)) { I18n.t("wikis.macro.page_not_found") }
|
||||
->(error) do
|
||||
inline_macro.with_leading_visual_icon(icon: :alert)
|
||||
render(Primer::Beta::Text.new(color: :muted)) { error_text(error) }
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
@@ -34,5 +34,16 @@ module Wikis
|
||||
include OpPrimer::ComponentHelpers
|
||||
|
||||
alias_method :page_info_result, :model
|
||||
|
||||
def error_text(error)
|
||||
case error
|
||||
in { code: :not_found }
|
||||
I18n.t("wikis.page_links.errors.page_not_found")
|
||||
in { code: :forbidden }
|
||||
I18n.t("wikis.page_links.errors.page_access_forbidden")
|
||||
else
|
||||
I18n.t("wikis.page_links.errors.unexpected")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -28,17 +28,27 @@ See COPYRIGHT and LICENSE files for more details.
|
||||
++#%>
|
||||
|
||||
<%= render(Primer::Alpha::Stack.new(direction: :horizontal, gap: :condensed, align: :center)) do %>
|
||||
<%= render(Primer::Beta::Octicon.new(icon: :"op-file-doc")) %>
|
||||
<%=
|
||||
if error?
|
||||
render(Primer::Beta::Octicon.new(icon: :alert, color: :muted))
|
||||
else
|
||||
render(Primer::Beta::Octicon.new(icon: :"op-file-doc"))
|
||||
end
|
||||
%>
|
||||
|
||||
<%=
|
||||
render(Primer::Alpha::StackItem.new(grow: true, classes: "ellipsis")) do
|
||||
render(Primer::Beta::Link.new(href: page_href, scheme: :primary)) { page_title }
|
||||
if error?
|
||||
render(Primer::Beta::Text.new(color: :muted)) { page_title }
|
||||
else
|
||||
render(Primer::Beta::Link.new(href: page_href, scheme: :primary)) { page_title }
|
||||
end
|
||||
end
|
||||
%>
|
||||
|
||||
<%=
|
||||
if show_action_menu?
|
||||
render(Primer::Alpha::ActionMenu.new) do |menu|
|
||||
render(Primer::Alpha::ActionMenu.new(test_selector: "wiki-page-link-action-menu")) do |menu|
|
||||
menu.with_show_button(icon: :"kebab-horizontal", "aria-label": t(:label_more), scheme: :invisible)
|
||||
menu_items(menu)
|
||||
end
|
||||
|
||||
@@ -45,17 +45,31 @@ module Wikis
|
||||
end
|
||||
|
||||
def page_title
|
||||
# TODO: Define behaviour for errors
|
||||
page_info_result.either(->(pi) { pi.title }, ->(_) { "Nothing to see here" })
|
||||
page_info_result.either(
|
||||
->(pi) { pi.title },
|
||||
->(error) do
|
||||
case error
|
||||
in { code: :not_found }
|
||||
I18n.t("wikis.page_links.errors.page_not_found")
|
||||
in { code: :forbidden }
|
||||
I18n.t("wikis.page_links.errors.page_access_forbidden")
|
||||
else
|
||||
I18n.t("wikis.page_links.errors.unexpected")
|
||||
end
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
def page_href
|
||||
# TODO: Define behaviour for errors
|
||||
page_info_result.either(->(pi) { pi.href }, ->(_) { "#" })
|
||||
page_info_result.value!.href
|
||||
end
|
||||
|
||||
def error?
|
||||
page_info_result.failure?
|
||||
end
|
||||
|
||||
def show_action_menu?
|
||||
page_info_result.success? && actions.any?
|
||||
actions.any?
|
||||
end
|
||||
|
||||
def menu_items(menu)
|
||||
|
||||
@@ -14,7 +14,7 @@ en:
|
||||
universal_identifier: Universal identifier
|
||||
url: Instance URL
|
||||
wiki_audience: XWiki Audience
|
||||
errors: {}
|
||||
errors: { }
|
||||
models:
|
||||
wikis/inline_page_link:
|
||||
one: Inline page link
|
||||
@@ -57,6 +57,11 @@ en:
|
||||
work_package_wikis_tab_component:
|
||||
inline_page_links: Inline page links
|
||||
referencing_pages: Referenced in
|
||||
page_links:
|
||||
errors:
|
||||
page_not_found: Linked wiki page no longer available
|
||||
page_access_forbidden: You do not have permission to access this wiki page
|
||||
unexpected: An unexpected error occurred
|
||||
page_link_component:
|
||||
remove: Remove page link
|
||||
relation_page_links_component:
|
||||
@@ -135,5 +140,3 @@ en:
|
||||
openproject_oauth_description: Allow XWiki to access OpenProject data using an OAuth.
|
||||
xwiki_oauth: XWiki OAuth
|
||||
xwiki_oauth_description: Allow OpenProject to access XWiki data using an OAuth.
|
||||
macro:
|
||||
page_not_found: Linked wiki page no longer available
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
#-- 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.
|
||||
#++
|
||||
|
||||
require "spec_helper"
|
||||
require_module_spec_helper
|
||||
|
||||
RSpec.describe Wikis::PageLinkComponent, type: :component do
|
||||
let(:project) { create(:project) }
|
||||
let(:work_package) { create(:work_package, project:) }
|
||||
let(:provider) { create(:internal_wiki_provider) }
|
||||
let(:page_link) { create(:relation_wiki_page_link, linkable: work_package, provider:) }
|
||||
let(:page_info) do
|
||||
Wikis::Adapters::Results::PageInfo.new(
|
||||
identifier: page_link.identifier,
|
||||
title: "Stormtrooper training",
|
||||
provider:,
|
||||
href: "https://wiki.death.star/Home/stormtrooper_training"
|
||||
)
|
||||
end
|
||||
let(:page_info_result) { Success(page_info) }
|
||||
let(:permissions) { [:manage_wiki_page_links] }
|
||||
let(:actions) { [] }
|
||||
|
||||
current_user { create(:user, member_with_permissions: { project => permissions }) }
|
||||
|
||||
subject(:render_component) { render_inline(described_class.new(page_info_result, actions:, page_link:)) }
|
||||
|
||||
before { render_component }
|
||||
|
||||
it "renders the page link successfully" do
|
||||
expect(page).to have_link(text: page_info.title, href: page_info.href)
|
||||
end
|
||||
|
||||
context "when the page link has the remove action" do
|
||||
let(:actions) { [:remove] }
|
||||
|
||||
context "when the user has no permission to manage wiki page links" do
|
||||
let(:permissions) { [] }
|
||||
|
||||
it "does not render the action menu" do
|
||||
expect(page).not_to have_test_selector("wiki-page-link-action-menu")
|
||||
end
|
||||
end
|
||||
|
||||
context "when the user has the permission to manage wiki page links" do
|
||||
it "shows the remove page link action in the action menu" do
|
||||
expect(page).to have_test_selector("wiki-page-link-action-menu")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when the page link has no actions" do
|
||||
it "does not render the action menu" do
|
||||
expect(page).not_to have_test_selector("wiki-page-link-action-menu")
|
||||
end
|
||||
end
|
||||
|
||||
context "if there are errors retrieving the page info" do
|
||||
let(:page_info_result) do
|
||||
Failure(
|
||||
Wikis::Adapters::Results::Error.new(
|
||||
source: Wikis::Adapters::Providers::Internal::Queries::PageInfo,
|
||||
code: error_code
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
context "if the page was not found" do
|
||||
let(:error_code) { :not_found }
|
||||
|
||||
it "renders an error text" do
|
||||
expect(page).not_to have_link
|
||||
expect(page).to have_text(I18n.t("wikis.page_links.errors.page_not_found"))
|
||||
end
|
||||
end
|
||||
|
||||
context "if the page access is forbidden" do
|
||||
let(:error_code) { :forbidden }
|
||||
|
||||
it "renders an error text" do
|
||||
expect(page).not_to have_link
|
||||
expect(page).to have_text(I18n.t("wikis.page_links.errors.page_access_forbidden"))
|
||||
end
|
||||
end
|
||||
|
||||
context "if an unknown error occurred" do
|
||||
let(:error_code) { :timeout }
|
||||
|
||||
it "renders an error text" do
|
||||
expect(page).not_to have_link
|
||||
expect(page).to have_text(I18n.t("wikis.page_links.errors.unexpected"))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user