mirror of
https://github.com/opf/openproject.git
synced 2026-06-13 19:20:00 +00:00
Merge pull request #19421 from opf/bug/63777-breadcrumb-index-creates-unnecessary-navigation-buttons-on-mobile-web-2
[63777] Breadcrumb index creates unnecessary navigation buttons on mobile web
This commit is contained in:
@@ -422,4 +422,4 @@ end
|
||||
|
||||
gem "openproject-octicons", "~>19.25.0"
|
||||
gem "openproject-octicons_helper", "~>19.25.0"
|
||||
gem "openproject-primer_view_components", "~>0.70.2"
|
||||
gem "openproject-primer_view_components", "~>0.70.3"
|
||||
|
||||
+3
-3
@@ -861,7 +861,7 @@ GEM
|
||||
actionview
|
||||
openproject-octicons (= 19.25.0)
|
||||
railties
|
||||
openproject-primer_view_components (0.70.2)
|
||||
openproject-primer_view_components (0.70.3)
|
||||
actionview (>= 7.1.0)
|
||||
activesupport (>= 7.1.0)
|
||||
openproject-octicons (>= 19.25.0)
|
||||
@@ -1453,7 +1453,7 @@ DEPENDENCIES
|
||||
openproject-octicons (~> 19.25.0)
|
||||
openproject-octicons_helper (~> 19.25.0)
|
||||
openproject-openid_connect!
|
||||
openproject-primer_view_components (~> 0.70.2)
|
||||
openproject-primer_view_components (~> 0.70.3)
|
||||
openproject-recaptcha!
|
||||
openproject-reporting!
|
||||
openproject-storages!
|
||||
@@ -1827,7 +1827,7 @@ CHECKSUMS
|
||||
openproject-octicons (19.25.0) sha256=16fc221375e693f0e893b1c208286f2d7719ae4dfe080c5415642b221f51f550
|
||||
openproject-octicons_helper (19.25.0) sha256=9b1778a67b0015ebe84ca0471f74e31004b985a8dcaaa443f7a2ac365b0a4e2d
|
||||
openproject-openid_connect (1.0.0)
|
||||
openproject-primer_view_components (0.70.2) sha256=b08bc35f1edb00c583544e8757badf8914ba7e32c88a2eb187de53a6d688ba0a
|
||||
openproject-primer_view_components (0.70.3) sha256=ccfa81b533f66d6fa1a7268d38e5350d33717685e6cfe175f19816544ca080e2
|
||||
openproject-recaptcha (1.0.0)
|
||||
openproject-reporting (1.0.0)
|
||||
openproject-storages (1.0.0)
|
||||
|
||||
@@ -39,7 +39,7 @@ class Members::IndexPageHeaderComponent < ApplicationComponent
|
||||
|
||||
def breadcrumb_items
|
||||
[{ href: project_overview_path(@project.id), text: @project.name },
|
||||
{ href: project_members_path(@project), text: t(:label_member_plural) },
|
||||
{ href: project_members_path(@project), text: I18n.t(:label_member_plural), skip_for_mobile: first_menu_item? },
|
||||
current_breadcrumb_element]
|
||||
end
|
||||
|
||||
@@ -74,17 +74,27 @@ class Members::IndexPageHeaderComponent < ApplicationComponent
|
||||
|
||||
def current_query
|
||||
query_name = nil
|
||||
query_href = nil
|
||||
menu_header = nil
|
||||
|
||||
Members::Menu.new(project: @project, params:).menu_items.find do |section|
|
||||
section.children.find do |menu_query|
|
||||
if !!menu_query.selected
|
||||
query_name = menu_query.title
|
||||
query_href = menu_query.href
|
||||
menu_header = section.header
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
{ query_name:, menu_header: }
|
||||
{ query_name:, query_href:, menu_header: }
|
||||
end
|
||||
|
||||
def first_menu_item?
|
||||
if current_query.present?
|
||||
return current_query[:query_href] == project_members_path(@project)
|
||||
end
|
||||
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
@@ -46,8 +46,7 @@ module Notifications
|
||||
end
|
||||
|
||||
def breadcrumb_items
|
||||
[{ href: home_path, text: helpers.organization_name },
|
||||
{ href: notifications_path, text: I18n.t("js.notifications.title") },
|
||||
[{ href: notifications_path, text: I18n.t("js.notifications.title"), skip_for_mobile: first_menu_item? },
|
||||
current_breadcrumb_element]
|
||||
end
|
||||
|
||||
@@ -74,5 +73,9 @@ module Notifications
|
||||
.new(params:, current_user: User.current)
|
||||
.selected_menu_item
|
||||
end
|
||||
|
||||
def first_menu_item?
|
||||
current_item&.href == notifications_path
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -112,8 +112,7 @@ class Projects::IndexPageHeaderComponent < ApplicationComponent
|
||||
|
||||
def breadcrumb_items
|
||||
[
|
||||
{ href: home_path, text: helpers.organization_name },
|
||||
{ href: projects_path, text: t(:label_project_plural) },
|
||||
{ href: projects_path, text: t(:label_project_plural), skip_for_mobile: first_menu_item? },
|
||||
current_breadcrumb_element
|
||||
]
|
||||
end
|
||||
@@ -136,6 +135,11 @@ class Projects::IndexPageHeaderComponent < ApplicationComponent
|
||||
.selected_menu_group
|
||||
end
|
||||
|
||||
def first_menu_item?
|
||||
current_item = current_section&.children&.select { |x| x.selected == true }&.first
|
||||
current_item&.title == ::ProjectQueries::Static.query(ProjectQueries::Static::DEFAULT).name
|
||||
end
|
||||
|
||||
def header_save_action(header:, message:, label:, href:, method: nil)
|
||||
header.with_action_text { message }
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
header.with_breadcrumbs(
|
||||
[
|
||||
{ href: project_overview_path(@project.id), text: @project.name },
|
||||
{ href: project_settings_general_path(@project.id), text: I18n.t("label_project_settings") },
|
||||
{ href: project_settings_general_path(@project.id), text: I18n.t("label_project_settings"), skip_for_mobile: true },
|
||||
t(:label_information_plural)
|
||||
]
|
||||
)
|
||||
|
||||
@@ -34,7 +34,7 @@ module Settings
|
||||
def breadcrumbs_items
|
||||
[
|
||||
{ href: admin_index_path, text: t("label_administration") },
|
||||
{ href: admin_settings_project_custom_fields_path, text: t("label_project_plural") },
|
||||
{ href: admin_settings_project_custom_fields_path, text: t("label_project_plural"), skip_for_mobile: true },
|
||||
t("settings.project_phase_definitions.heading")
|
||||
]
|
||||
end
|
||||
|
||||
@@ -32,8 +32,7 @@ See COPYRIGHT and LICENSE files for more details.
|
||||
render Primer::OpenProject::PageHeader.new do |header|
|
||||
header.with_title { t(:label_password_lost) }
|
||||
header.with_breadcrumbs(
|
||||
[{ href: home_path, text: organization_name },
|
||||
t(:label_password_lost)]
|
||||
[t(:label_password_lost)]
|
||||
)
|
||||
end
|
||||
%>
|
||||
|
||||
@@ -32,8 +32,7 @@ See COPYRIGHT and LICENSE files for more details.
|
||||
render Primer::OpenProject::PageHeader.new do |header|
|
||||
header.with_title { t(:label_password_lost) }
|
||||
header.with_breadcrumbs(
|
||||
[{ href: home_path, text: organization_name },
|
||||
t(:label_password_lost)]
|
||||
[t(:label_password_lost)]
|
||||
)
|
||||
end
|
||||
%>
|
||||
|
||||
@@ -34,9 +34,10 @@ See COPYRIGHT and LICENSE files for more details.
|
||||
header.with_title { (@author.nil? ? t(:label_activity) : t(:label_user_activity, value: link_to_user(@author))).html_safe }
|
||||
header.with_description { t(:label_date_from_to, start: format_date(@date_to - @days), end: format_date(@date_to - 1)) }
|
||||
header.with_breadcrumbs(
|
||||
[*([href: home_path, text: organization_name] unless @project),
|
||||
*([href: project_overview_path(@project.id), text: @project.name] if @project),
|
||||
t(:label_activity)]
|
||||
[
|
||||
({ href: project_overview_path(@project.id), text: @project.name } if @project),
|
||||
t(:label_activity)
|
||||
].compact
|
||||
)
|
||||
end
|
||||
%>
|
||||
|
||||
@@ -33,7 +33,7 @@ See COPYRIGHT and LICENSE files for more details.
|
||||
render(Primer::OpenProject::PageHeader.new) do |header|
|
||||
header.with_title { t(:label_overview) }
|
||||
header.with_breadcrumbs(
|
||||
[{ href: admin_index_path, text: t(:label_administration) },
|
||||
[{ href: admin_index_path, text: t(:label_administration), skip_for_mobile: true },
|
||||
t(:label_overview)]
|
||||
)
|
||||
end
|
||||
|
||||
@@ -34,7 +34,7 @@ See COPYRIGHT and LICENSE files for more details.
|
||||
header.with_title { t(:"menus.admin.aggregation") }
|
||||
header.with_breadcrumbs(
|
||||
[{ href: admin_index_path, text: t(:label_administration) },
|
||||
{ href: admin_settings_aggregation_path, text: t(:"menus.admin.mails_and_notifications") },
|
||||
{ href: admin_settings_aggregation_path, text: t(:"menus.admin.mails_and_notifications"), skip_for_mobile: true },
|
||||
t(:"menus.admin.aggregation")]
|
||||
)
|
||||
end
|
||||
|
||||
@@ -33,7 +33,7 @@ See COPYRIGHT and LICENSE files for more details.
|
||||
header.with_title { t(:label_api_access_key_type) }
|
||||
header.with_breadcrumbs(
|
||||
[{ href: admin_index_path, text: t("label_administration") },
|
||||
{ href: admin_settings_api_path, text: t("menus.admin.api_and_webhooks") },
|
||||
{ href: admin_settings_api_path, text: t("menus.admin.api_and_webhooks"), skip_for_mobile: true },
|
||||
t(:label_api_access_key_type)]
|
||||
)
|
||||
end
|
||||
|
||||
@@ -55,7 +55,7 @@ See COPYRIGHT and LICENSE files for more details.
|
||||
header.with_title { t("authentication.login_and_registration") }
|
||||
header.with_breadcrumbs(
|
||||
[{ href: admin_index_path, text: t(:label_administration) },
|
||||
{ href: admin_settings_authentication_path, text: t(:label_authentication) },
|
||||
{ href: admin_settings_authentication_path, text: t(:label_authentication), skip_for_mobile: true },
|
||||
t("authentication.login_and_registration")]
|
||||
)
|
||||
render_tab_header_nav(header, tabs)
|
||||
|
||||
@@ -34,7 +34,7 @@ See COPYRIGHT and LICENSE files for more details.
|
||||
header.with_title { t(:label_general) }
|
||||
header.with_breadcrumbs(
|
||||
[{ href: admin_index_path, text: t("label_administration") },
|
||||
{ href: admin_settings_general_path, text: t(:label_system_settings) },
|
||||
{ href: admin_settings_general_path, text: t(:label_system_settings), skip_for_mobile: true },
|
||||
t(:label_general)]
|
||||
)
|
||||
end
|
||||
|
||||
@@ -33,7 +33,7 @@ See COPYRIGHT and LICENSE files for more details.
|
||||
header.with_title { t(:label_user_settings) }
|
||||
header.with_breadcrumbs(
|
||||
[{ href: admin_index_path, text: t("label_administration") },
|
||||
{ href: admin_settings_users_path, text: t(:label_user_and_permission) },
|
||||
{ href: admin_settings_users_path, text: t(:label_user_and_permission), skip_for_mobile: true },
|
||||
t(:label_user_settings)]
|
||||
)
|
||||
end
|
||||
|
||||
@@ -34,7 +34,7 @@ See COPYRIGHT and LICENSE files for more details.
|
||||
header.with_title { t(:label_general) }
|
||||
header.with_breadcrumbs(
|
||||
[{ href: admin_index_path, text: t("label_administration") },
|
||||
{ href: admin_settings_work_packages_general_path, text: t(:label_work_package_plural) },
|
||||
{ href: admin_settings_work_packages_general_path, text: t(:label_work_package_plural), skip_for_mobile: true },
|
||||
t(:label_general)]
|
||||
)
|
||||
end
|
||||
|
||||
@@ -34,7 +34,7 @@ See COPYRIGHT and LICENSE files for more details.
|
||||
header.with_title(test_selector: "op-working-days-admin-settings--title") { t(:label_working_days_and_hours) }
|
||||
header.with_breadcrumbs(
|
||||
[{ href: admin_index_path, text: t("label_administration") },
|
||||
{ href: admin_settings_working_days_and_hours_path, text: t(:label_calendars_and_dates) },
|
||||
{ href: admin_settings_working_days_and_hours_path, text: t(:label_calendars_and_dates), skip_for_mobile: true },
|
||||
t(:label_working_days_and_hours)]
|
||||
)
|
||||
end
|
||||
|
||||
@@ -29,7 +29,7 @@ See COPYRIGHT and LICENSE files for more details.
|
||||
<%=
|
||||
render(Primer::OpenProject::PageHeader.new) do |header|
|
||||
header.with_title { I18n.t("label_home") }
|
||||
header.with_breadcrumbs([{ href: home_path, text: organization_name }, I18n.t(:label_home)])
|
||||
header.with_breadcrumbs([I18n.t(:label_home)], skip_home_on_mobile: true)
|
||||
end
|
||||
%>
|
||||
|
||||
@@ -52,7 +52,7 @@ See COPYRIGHT and LICENSE files for more details.
|
||||
|
||||
<% @homescreen[:links].each do |link| %>
|
||||
<% title = I18n.t(link[:label], scope: "homescreen.links") %>
|
||||
<a class="homescreen--links--item" href="<%= link[:url] %>" target="_blank" title="<%= title %>">
|
||||
<a class="homescreen--links--item" href="<%= link[:url] %>" target="_blank" aria-label="<%= title %>">
|
||||
<%= op_icon(link[:icon]) %>
|
||||
<%= title %>
|
||||
</a>
|
||||
|
||||
@@ -33,7 +33,7 @@ See COPYRIGHT and LICENSE files for more details.
|
||||
render(Primer::OpenProject::PageHeader.new) do |header|
|
||||
header.with_title { t(:label_profile) }
|
||||
header.with_breadcrumbs(
|
||||
[{ href: my_account_path, text: t(:label_my_account) },
|
||||
[{ href: my_account_path, text: t(:label_my_account), skip_for_mobile: true },
|
||||
t(:label_profile)]
|
||||
)
|
||||
end
|
||||
|
||||
@@ -32,10 +32,11 @@ See COPYRIGHT and LICENSE files for more details.
|
||||
render Primer::OpenProject::PageHeader.new do |header|
|
||||
header.with_title { @news.title }
|
||||
header.with_breadcrumbs(
|
||||
[*([href: home_path, text: organization_name] unless @project),
|
||||
*([href: project_overview_path(@project.id), text: @project.name] if @project),
|
||||
*([href: project_news_index_path(@project.id), text: t(:label_news_plural)] if @project),
|
||||
@news.title]
|
||||
[
|
||||
({ href: project_overview_path(@project.id), text: @project.name } if @project),
|
||||
({ href: project_news_index_path(@project.id), text: t(:label_news_plural) } if @project),
|
||||
@news.title
|
||||
].compact
|
||||
)
|
||||
end
|
||||
%>
|
||||
|
||||
@@ -37,9 +37,10 @@ See COPYRIGHT and LICENSE files for more details.
|
||||
render Primer::OpenProject::PageHeader.new do |header|
|
||||
header.with_title { t(:label_news_plural) }
|
||||
header.with_breadcrumbs(
|
||||
[*([href: home_path, text: organization_name] unless @project),
|
||||
*([href: project_overview_path(@project.id), text: @project.name] if @project),
|
||||
t(:label_news_plural)]
|
||||
[
|
||||
({ href: project_overview_path(@project.id), text: @project.name } if @project),
|
||||
t(:label_news_plural)
|
||||
].compact
|
||||
)
|
||||
end
|
||||
%>
|
||||
|
||||
@@ -31,10 +31,11 @@ See COPYRIGHT and LICENSE files for more details.
|
||||
render Primer::OpenProject::PageHeader.new do |header|
|
||||
header.with_title { "#{avatar(@news.author)} #{h @news.title}".html_safe }
|
||||
header.with_breadcrumbs(
|
||||
[*([href: home_path, text: organization_name] unless @project),
|
||||
*([href: project_overview_path(@project.id), text: @project.name] if @project),
|
||||
*([href: project_news_index_path(@project.id), text: t(:label_news_plural)] if @project),
|
||||
@news.title]
|
||||
[
|
||||
({ href: project_overview_path(@project.id), text: @project.name } if @project),
|
||||
({ href: project_news_index_path(@project.id), text: t(:label_news_plural) } if @project),
|
||||
@news.title
|
||||
].compact
|
||||
)
|
||||
if User.current.allowed_in_project?(:manage_news, @project)
|
||||
header.with_action_button(
|
||||
|
||||
@@ -30,7 +30,7 @@ See COPYRIGHT and LICENSE files for more details.
|
||||
<%=
|
||||
render(Primer::OpenProject::PageHeader.new) do |header|
|
||||
header.with_title { t(:label_project_new) }
|
||||
header.with_breadcrumbs([{ href: home_path, text: organization_name }, t(:label_project_new)])
|
||||
header.with_breadcrumbs([t(:label_project_new)])
|
||||
end
|
||||
%>
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ See COPYRIGHT and LICENSE files for more details.
|
||||
header.with_breadcrumbs(
|
||||
[
|
||||
{ href: project_overview_path(@project.id), text: @project.name },
|
||||
{ href: url_for({ controller: "/wiki", action: "index", project_id: @project.identifier, id: @related_page }), text: t("activerecord.models.wiki") },
|
||||
{ href: url_for({ controller: "/wiki", action: "index", project_id: @project.identifier, id: @related_page }), text: t("activerecord.models.wiki"), skip_for_mobile: true },
|
||||
t(:label_wiki_toc)
|
||||
]
|
||||
)
|
||||
|
||||
Generated
+14
-14
@@ -53,12 +53,12 @@
|
||||
"@ngneat/content-loader": "^7.0.0",
|
||||
"@ngx-formly/core": "^6.1.4",
|
||||
"@openproject/octicons-angular": "^19.25.0",
|
||||
"@openproject/primer-view-components": "^0.70.2",
|
||||
"@openproject/primer-view-components": "^0.70.3",
|
||||
"@openproject/reactivestates": "^3.0.1",
|
||||
"@primer/css": "^21.5.0",
|
||||
"@primer/live-region-element": "^0.8.0",
|
||||
"@primer/primitives": "^10.6.0",
|
||||
"@primer/view-components": "npm:@openproject/primer-view-components@^0.70.2",
|
||||
"@primer/view-components": "npm:@openproject/primer-view-components@^0.70.3",
|
||||
"@stimulus-components/auto-submit": "^6.0.0",
|
||||
"@types/hotwired__turbo": "^8.0.1",
|
||||
"@uirouter/angular": "^13.0.0",
|
||||
@@ -4907,9 +4907,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@openproject/primer-view-components": {
|
||||
"version": "0.70.2",
|
||||
"resolved": "https://registry.npmjs.org/@openproject/primer-view-components/-/primer-view-components-0.70.2.tgz",
|
||||
"integrity": "sha512-h/2m1Ott9n1awZQRA26bNbex9g6NItBI1/sPDIWBVlQovy5pVJOx1LBjgv8W8VBCwKCJwWoTarK7Ln6JrNkc5A==",
|
||||
"version": "0.70.3",
|
||||
"resolved": "https://registry.npmjs.org/@openproject/primer-view-components/-/primer-view-components-0.70.3.tgz",
|
||||
"integrity": "sha512-b/cNIpxfXWcaQzq282EqobEtqUZ6oTCrPilHRGEhJCkM4JVDZIbN9UvXZjuORGfs3s53Q1HACL1q5Q7/BTHP2Q==",
|
||||
"dependencies": {
|
||||
"@github/auto-check-element": "^6.0.0",
|
||||
"@github/auto-complete-element": "^3.8.0",
|
||||
@@ -4996,9 +4996,9 @@
|
||||
},
|
||||
"node_modules/@primer/view-components": {
|
||||
"name": "@openproject/primer-view-components",
|
||||
"version": "0.70.2",
|
||||
"resolved": "https://registry.npmjs.org/@openproject/primer-view-components/-/primer-view-components-0.70.2.tgz",
|
||||
"integrity": "sha512-h/2m1Ott9n1awZQRA26bNbex9g6NItBI1/sPDIWBVlQovy5pVJOx1LBjgv8W8VBCwKCJwWoTarK7Ln6JrNkc5A==",
|
||||
"version": "0.70.3",
|
||||
"resolved": "https://registry.npmjs.org/@openproject/primer-view-components/-/primer-view-components-0.70.3.tgz",
|
||||
"integrity": "sha512-b/cNIpxfXWcaQzq282EqobEtqUZ6oTCrPilHRGEhJCkM4JVDZIbN9UvXZjuORGfs3s53Q1HACL1q5Q7/BTHP2Q==",
|
||||
"dependencies": {
|
||||
"@github/auto-check-element": "^6.0.0",
|
||||
"@github/auto-complete-element": "^3.8.0",
|
||||
@@ -28326,9 +28326,9 @@
|
||||
}
|
||||
},
|
||||
"@openproject/primer-view-components": {
|
||||
"version": "0.70.2",
|
||||
"resolved": "https://registry.npmjs.org/@openproject/primer-view-components/-/primer-view-components-0.70.2.tgz",
|
||||
"integrity": "sha512-h/2m1Ott9n1awZQRA26bNbex9g6NItBI1/sPDIWBVlQovy5pVJOx1LBjgv8W8VBCwKCJwWoTarK7Ln6JrNkc5A==",
|
||||
"version": "0.70.3",
|
||||
"resolved": "https://registry.npmjs.org/@openproject/primer-view-components/-/primer-view-components-0.70.3.tgz",
|
||||
"integrity": "sha512-b/cNIpxfXWcaQzq282EqobEtqUZ6oTCrPilHRGEhJCkM4JVDZIbN9UvXZjuORGfs3s53Q1HACL1q5Q7/BTHP2Q==",
|
||||
"requires": {
|
||||
"@github/auto-check-element": "^6.0.0",
|
||||
"@github/auto-complete-element": "^3.8.0",
|
||||
@@ -28394,9 +28394,9 @@
|
||||
"integrity": "sha512-732Dq7c4znkewwRkXldV0NLLppfGrDJHPXsXO2QLHwJxKLwi2icKkzcOR77vb5g0ThObZJrRqlB/4DYajIiyyQ=="
|
||||
},
|
||||
"@primer/view-components": {
|
||||
"version": "npm:@openproject/primer-view-components@0.70.2",
|
||||
"resolved": "https://registry.npmjs.org/@openproject/primer-view-components/-/primer-view-components-0.70.2.tgz",
|
||||
"integrity": "sha512-h/2m1Ott9n1awZQRA26bNbex9g6NItBI1/sPDIWBVlQovy5pVJOx1LBjgv8W8VBCwKCJwWoTarK7Ln6JrNkc5A==",
|
||||
"version": "npm:@openproject/primer-view-components@0.70.3",
|
||||
"resolved": "https://registry.npmjs.org/@openproject/primer-view-components/-/primer-view-components-0.70.3.tgz",
|
||||
"integrity": "sha512-b/cNIpxfXWcaQzq282EqobEtqUZ6oTCrPilHRGEhJCkM4JVDZIbN9UvXZjuORGfs3s53Q1HACL1q5Q7/BTHP2Q==",
|
||||
"requires": {
|
||||
"@github/auto-check-element": "^6.0.0",
|
||||
"@github/auto-complete-element": "^3.8.0",
|
||||
|
||||
@@ -105,12 +105,12 @@
|
||||
"@ngneat/content-loader": "^7.0.0",
|
||||
"@ngx-formly/core": "^6.1.4",
|
||||
"@openproject/octicons-angular": "^19.25.0",
|
||||
"@openproject/primer-view-components": "^0.70.2",
|
||||
"@openproject/primer-view-components": "^0.70.3",
|
||||
"@openproject/reactivestates": "^3.0.1",
|
||||
"@primer/css": "^21.5.0",
|
||||
"@primer/live-region-element": "^0.8.0",
|
||||
"@primer/primitives": "^10.6.0",
|
||||
"@primer/view-components": "npm:@openproject/primer-view-components@^0.70.2",
|
||||
"@primer/view-components": "npm:@openproject/primer-view-components@^0.70.3",
|
||||
"@stimulus-components/auto-submit": "^6.0.0",
|
||||
"@types/hotwired__turbo": "^8.0.1",
|
||||
"@uirouter/angular": "^13.0.0",
|
||||
|
||||
@@ -179,6 +179,7 @@ export class IFCViewerPageComponent extends PartitionedQuerySpacePageComponent i
|
||||
|
||||
breadcrumbItems() {
|
||||
return [
|
||||
{ href: this.pathHelperService.homePath(), text: this.titleService.appTitle },
|
||||
{ href: this.pathHelperService.projectPath(this.currentProject.identifier as string), text: (this.currentProject.name) },
|
||||
{ href: this.pathHelperService.projectBCFPath(this.currentProject.identifier as string), text: this.I18n.t('js.bcf.label_bcf') },
|
||||
this.selectedTitle?? '',
|
||||
|
||||
+1
@@ -200,6 +200,7 @@ export class BoardPartitionedPageComponent extends UntilDestroyedMixin {
|
||||
|
||||
breadcrumbItems() {
|
||||
return [
|
||||
{ href: this.pathHelperService.homePath(), text: this.titleService.appTitle },
|
||||
{ href: this.pathHelperService.projectPath(this.currentProject.identifier as string), text: (this.currentProject.name) },
|
||||
{ href: this.pathHelperService.boardsPath(this.currentProject.identifier as string), text: this.I18n.t('js.label_board_plural') },
|
||||
this.selectedTitle?? '',
|
||||
|
||||
@@ -74,6 +74,7 @@ export class WorkPackagesCalendarPageComponent extends PartitionedQuerySpacePage
|
||||
|
||||
breadcrumbItems() {
|
||||
return [
|
||||
{ href: this.pathHelperService.homePath(), text: this.titleService.appTitle },
|
||||
{ href: this.pathHelperService.projectPath(this.currentProject.identifier as string), text: (this.currentProject.name) },
|
||||
{ href: this.pathHelperService.projectCalendarPath(this.currentProject.identifier as string), text: this.I18n.t('js.calendar.label_calendar_plural') },
|
||||
this.selectedTitle?? '',
|
||||
|
||||
+1
@@ -125,6 +125,7 @@ export class TeamPlannerPageComponent extends PartitionedQuerySpacePageComponent
|
||||
|
||||
breadcrumbItems() {
|
||||
return [
|
||||
{ href: this.pathHelperService.homePath(), text: this.titleService.appTitle },
|
||||
{ href: this.pathHelperService.projectPath(this.currentProject.identifier as string), text: (this.currentProject.name) },
|
||||
{ href: this.pathHelperService.projectTeamplannerPath(this.currentProject.identifier as string), text: this.I18n.t('js.team_planner.label_team_planner_plural') },
|
||||
this.selectedTitle?? '',
|
||||
|
||||
+8
-7
@@ -45,6 +45,7 @@ import { of } from 'rxjs';
|
||||
import { WorkPackageFoldToggleButtonComponent } from 'core-app/features/work-packages/components/wp-buttons/wp-fold-toggle-button/wp-fold-toggle-button.component';
|
||||
import { OpProjectIncludeComponent } from 'core-app/shared/components/project-include/project-include.component';
|
||||
import { OpBaselineModalComponent } from 'core-app/features/work-packages/components/wp-baseline/baseline-modal/baseline-modal.component';
|
||||
import { BreadcrumbItem } from 'core-app/shared/components/breadcrumbs/op-breadcrumbs.component';
|
||||
|
||||
@Component({
|
||||
selector: 'wp-view-page',
|
||||
@@ -109,20 +110,20 @@ export class WorkPackageViewPageComponent extends PartitionedQuerySpacePageCompo
|
||||
}
|
||||
|
||||
breadcrumbItems() {
|
||||
const items = [];
|
||||
const items:BreadcrumbItem[] = [{
|
||||
href: this.pathHelperService.homePath(),
|
||||
text: this.titleService.appTitle,
|
||||
}];
|
||||
|
||||
if (this.currentProject?.identifier) {
|
||||
items.push({
|
||||
href: this.pathHelperService.projectPath(this.currentProject.identifier),
|
||||
text: this.currentProject.name,
|
||||
});
|
||||
} else {
|
||||
items.push({
|
||||
href: this.pathHelperService.homePath(),
|
||||
text: this.titleService.appTitle,
|
||||
text: this.currentProject.name as string,
|
||||
});
|
||||
}
|
||||
|
||||
items.push(this.breadcrumbModuleEntry());
|
||||
|
||||
if (this.selectedTitle) {
|
||||
items.push(this.selectedTitle);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
# 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.
|
||||
#++
|
||||
|
||||
module OpenProject
|
||||
module Patches
|
||||
module PrimerPageHeaderBreadcrumb
|
||||
def with_breadcrumbs(breadcrumbs, skip_home_on_mobile: false, **)
|
||||
super([{ href: home_path,
|
||||
text: helpers.organization_name,
|
||||
skip_for_mobile: skip_home_on_mobile }] + breadcrumbs, **)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
OpenProject::Patches.patch_gem_version "openproject-primer_view_components", "0.70.3" do
|
||||
Primer::OpenProject::PageHeader.prepend OpenProject::Patches::PrimerPageHeaderBreadcrumb
|
||||
end
|
||||
@@ -13,7 +13,8 @@ There are minor adjustments on how the composition of this component is defined
|
||||
- **Desktop:** The content of the context bar will be a [breadcrumb](https://primer.style/components/breadcrumbs).
|
||||
- **Tablet:** The content of the context bar will be a [breadcrumb](https://primer.style/components/breadcrumbs).
|
||||
- **Mobile:**
|
||||
- The content of the breadcrumb will collapse to a single element using the parent link style.
|
||||
- The content of the breadcrumb will collapse to a single element using the parent link style. The text and href for that link will be taken from the second-last item of the breadcrumb, (which should be the parent of the current page).
|
||||
The only exception to that behavior are index pages, where the parent link might lead to the page itself again. To avoid these kind of loops on mobile, we can exclude certain elements from being taken as a mobile back link. An example can be found the [component previews](../../inspect/primer/open_project/page_header/skip_breadcrumb_item).
|
||||
- All the PageHeader actions will merge into an [ActionMenu](https://primer.style/components/action-menu) triggered by a single [Icon button](https://primer.style/components/icon-button) in the context bar.
|
||||
|
||||
**[Title bar](https://primer.style/components/page-header#title-bar):** The default (medium) size will be always used keeping the capability as optionals of adding leading and trailing visuals and actions.
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
header.with_title { t("saml.providers.plural") }
|
||||
header.with_breadcrumbs(
|
||||
[{ href: admin_index_path, text: t("label_administration") },
|
||||
{ href: admin_settings_authentication_path, text: t(:label_authentication) },
|
||||
t("saml.providers.plural")]
|
||||
)
|
||||
end %>
|
||||
@@ -23,5 +24,5 @@
|
||||
end %>
|
||||
<% end %>
|
||||
|
||||
<%= render EnterpriseEdition::BannerComponent.new(:sso_auth_providers, i18n_scope: "saml.providers.upsell")%>
|
||||
<%= render EnterpriseEdition::BannerComponent.new(:sso_auth_providers, i18n_scope: "saml.providers.upsell") %>
|
||||
<%= render ::Saml::Providers::TableComponent.new(rows: @providers) %>
|
||||
|
||||
@@ -33,9 +33,10 @@ See COPYRIGHT and LICENSE files for more details.
|
||||
render Primer::OpenProject::PageHeader.new do |header|
|
||||
header.with_title { t("boards.label_boards") }
|
||||
header.with_breadcrumbs(
|
||||
[*([href: home_path, text: organization_name] unless @project),
|
||||
*([href: project_overview_path(@project.id), text: @project.name] if @project),
|
||||
t("boards.label_boards")]
|
||||
[
|
||||
({ href: project_overview_path(@project.id), text: @project.name } if @project),
|
||||
t("boards.label_boards")
|
||||
].compact
|
||||
)
|
||||
end
|
||||
%>
|
||||
|
||||
@@ -33,10 +33,11 @@ See COPYRIGHT and LICENSE files for more details.
|
||||
render Primer::OpenProject::PageHeader.new do |header|
|
||||
header.with_title { t("boards.label_create_new_board") }
|
||||
header.with_breadcrumbs(
|
||||
[*([href: home_path, text: organization_name] unless @project),
|
||||
*([href: project_overview_path(@project.id), text: @project.name] if @project),
|
||||
*([href: project_work_package_boards_path(@project.id), text: t("boards.label_boards")] if @project),
|
||||
t("boards.label_create_new_board")]
|
||||
[
|
||||
({ href: project_overview_path(@project.id), text: @project.name } if @project),
|
||||
({ href: project_work_package_boards_path(@project.id), text: t("boards.label_boards") } if @project),
|
||||
t("boards.label_create_new_board")
|
||||
].compact
|
||||
)
|
||||
end
|
||||
%>
|
||||
|
||||
@@ -32,9 +32,10 @@ See COPYRIGHT and LICENSE files for more details.
|
||||
render Primer::OpenProject::PageHeader.new do |header|
|
||||
header.with_title { t(:label_calendar_plural) }
|
||||
header.with_breadcrumbs(
|
||||
[*([href: home_path, text: organization_name] unless @project),
|
||||
*([href: project_overview_path(@project.id), text: @project.name] if @project),
|
||||
t(:label_calendar_plural)]
|
||||
[
|
||||
({ href: project_overview_path(@project.id), text: @project.name } if @project),
|
||||
t(:label_calendar_plural)
|
||||
].compact
|
||||
)
|
||||
end
|
||||
%>
|
||||
|
||||
@@ -33,8 +33,7 @@ See COPYRIGHT and LICENSE files for more details.
|
||||
render Primer::OpenProject::PageHeader.new do |header|
|
||||
header.with_title { t(:label_new_calendar) }
|
||||
header.with_breadcrumbs(
|
||||
[{ href: home_path, text: organization_name },
|
||||
{ href: calendars_path, text: t(:label_calendar_plural) },
|
||||
[{ href: calendars_path, text: t(:label_calendar_plural) },
|
||||
t(:label_new_calendar)]
|
||||
)
|
||||
end
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
header.with_title { I18n.t(:label_my_time_tracking) }
|
||||
header.with_breadcrumbs(
|
||||
[
|
||||
{ href: home_path, text: helpers.organization_name },
|
||||
{ text: I18n.t(:label_my_time_tracking), href: my_time_tracking_path }
|
||||
]
|
||||
)
|
||||
|
||||
@@ -35,7 +35,7 @@ See COPYRIGHT and LICENSE files for more details.
|
||||
header.with_breadcrumbs(
|
||||
[
|
||||
{ href: admin_index_path, text: t("label_administration") },
|
||||
{ href: admin_costs_settings_path, text: t(:project_module_costs) },
|
||||
{ href: admin_costs_settings_path, text: t(:project_module_costs), skip_for_mobile: true },
|
||||
t(:label_defaults)
|
||||
]
|
||||
)
|
||||
|
||||
@@ -34,7 +34,7 @@ See COPYRIGHT and LICENSE files for more details.
|
||||
[{ href: project_overview_path(@project.identifier), text: @project.name },
|
||||
{ href: projects_budgets_path(@project.identifier), text: I18n.t(:label_budget_plural) }]
|
||||
else
|
||||
[{ href: home_path, text: organization_name }]
|
||||
[]
|
||||
end
|
||||
%>
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ See COPYRIGHT and LICENSE files for more details.
|
||||
[{ href: project_overview_path(@project.identifier), text: @project.name },
|
||||
{ href: projects_budgets_path(@project.identifier), text: I18n.t(:label_budget_plural) }]
|
||||
else
|
||||
[{ href: home_path, text: organization_name }]
|
||||
[]
|
||||
end
|
||||
%>
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ module Meetings
|
||||
|
||||
def breadcrumb_items
|
||||
[
|
||||
parent_element,
|
||||
({ href: project_overview_path(@project.id), text: @project.name } if @project.present?),
|
||||
{ href: @project.present? ? project_meetings_path(@project.id) : meetings_path,
|
||||
text: I18n.t(:label_meeting_plural) },
|
||||
meeting_series_element,
|
||||
@@ -99,14 +99,6 @@ module Meetings
|
||||
end
|
||||
end
|
||||
|
||||
def parent_element
|
||||
if @project.present?
|
||||
{ href: project_overview_path(@project.id), text: @project.name }
|
||||
else
|
||||
{ href: home_path, text: helpers.organization_name }
|
||||
end
|
||||
end
|
||||
|
||||
def delete_label
|
||||
if @series.present?
|
||||
I18n.t("label_recurring_meeting_cancel")
|
||||
|
||||
@@ -46,18 +46,12 @@ module Meetings
|
||||
end
|
||||
|
||||
def breadcrumb_items
|
||||
[parent_element,
|
||||
{ href: url_for({ controller: "meetings", action: :index, project_id: @project }),
|
||||
text: I18n.t(:label_meeting_plural) },
|
||||
current_breadcrumb_element]
|
||||
end
|
||||
|
||||
def parent_element
|
||||
if @project.present?
|
||||
{ href: project_overview_path(@project.id), text: @project.name }
|
||||
else
|
||||
{ href: home_path, text: helpers.organization_name }
|
||||
end
|
||||
[
|
||||
({ href: project_overview_path(@project.id), text: @project.name } if @project.present?),
|
||||
{ href: url_for({ controller: "meetings", action: :index, project_id: @project }),
|
||||
text: I18n.t(:label_meeting_plural), skip_for_mobile: first_menu_item? },
|
||||
current_breadcrumb_element
|
||||
].compact
|
||||
end
|
||||
|
||||
def current_breadcrumb_element
|
||||
@@ -87,5 +81,9 @@ module Meetings
|
||||
.new(project: @project, params: params.merge(current_href: request.path))
|
||||
.selected_menu_item
|
||||
end
|
||||
|
||||
def first_menu_item?
|
||||
current_item&.href == (@project.present? ? project_meetings_path(@project.identifier) : meetings_path)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -83,18 +83,12 @@ module RecurringMeetings
|
||||
end
|
||||
|
||||
def breadcrumb_items
|
||||
[parent_element,
|
||||
{ href: @project.present? ? project_meetings_path(@project.id) : meetings_path,
|
||||
text: I18n.t(:label_meeting_plural) },
|
||||
page_title(true)]
|
||||
end
|
||||
|
||||
def parent_element
|
||||
if @project.present?
|
||||
{ href: project_overview_path(@project.id), text: @project.name }
|
||||
else
|
||||
{ href: home_path, text: I18n.t(:label_home) }
|
||||
end
|
||||
[
|
||||
({ href: project_overview_path(@project.id), text: @project.name } if @project.present?),
|
||||
{ href: @project.present? ? project_meetings_path(@project.id) : meetings_path,
|
||||
text: I18n.t(:label_meeting_plural) },
|
||||
page_title(true)
|
||||
].compact
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -31,14 +31,12 @@ See COPYRIGHT and LICENSE files for more details.
|
||||
render(Primer::OpenProject::PageHeader.new) do |header|
|
||||
header.with_title { t(:label_recurring_meeting_new) }
|
||||
header.with_breadcrumbs(
|
||||
[if @project.present?
|
||||
{ href: project_overview_path(@project.id), text: @project.name }
|
||||
else
|
||||
{ href: home_path, text: I18n.t(:label_home) }
|
||||
end,
|
||||
{ href: @project.present? ? project_recurring_meetings_path(@project.id) : recurring_meetings_path,
|
||||
text: I18n.t(:label_meeting_plural) },
|
||||
t(:label_recurring_meeting_new)]
|
||||
[
|
||||
({ href: project_overview_path(@project.id), text: @project.name } if @project.present?),
|
||||
{ href: @project.present? ? project_recurring_meetings_path(@project.id) : recurring_meetings_path,
|
||||
text: I18n.t(:label_meeting_plural) },
|
||||
t(:label_recurring_meeting_new)
|
||||
].compact
|
||||
)
|
||||
end
|
||||
%>
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
header.with_title { t("my_page.label") }
|
||||
header.with_breadcrumbs(
|
||||
[
|
||||
{ href: home_path, text: organization_name },
|
||||
t("my_page.label")
|
||||
]
|
||||
)
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
header.with_title(variant: :medium) { t("overviews.label") }
|
||||
header.with_breadcrumbs(
|
||||
[
|
||||
{ href: project_path(@project), text: @project.name },
|
||||
{ href: project_path(@project), text: @project.name, skip_for_mobile: true },
|
||||
t("overviews.label")
|
||||
]
|
||||
)
|
||||
|
||||
@@ -39,23 +39,14 @@ module CostReports
|
||||
@user = User.current
|
||||
end
|
||||
|
||||
def page_title
|
||||
I18n.t(:label_meeting_plural)
|
||||
end
|
||||
|
||||
def breadcrumb_items
|
||||
[parent_element,
|
||||
{ href: url_for({ controller: "cost_reports", action: :index, project_id: @project }),
|
||||
text: I18n.t(:cost_reports_title) },
|
||||
current_breadcrumb_element]
|
||||
end
|
||||
|
||||
def parent_element
|
||||
if @project.present?
|
||||
{ href: project_overview_path(@project.id), text: @project.name }
|
||||
else
|
||||
{ href: home_path, text: helpers.organization_name }
|
||||
end
|
||||
[
|
||||
({ href: project_overview_path(@project.id), text: @project.name } if @project.present?),
|
||||
{ href: module_path,
|
||||
text: I18n.t(:cost_reports_title),
|
||||
skip_for_mobile: !current_section || current_section.header.blank? },
|
||||
current_breadcrumb_element
|
||||
].compact
|
||||
end
|
||||
|
||||
def current_breadcrumb_element
|
||||
@@ -79,5 +70,9 @@ module CostReports
|
||||
def show_export_button?
|
||||
@user.allowed_in_any_work_package?(:export_work_packages, in_project: @project)
|
||||
end
|
||||
|
||||
def module_path
|
||||
@project.present? ? cost_reports_path(@project) : global_cost_reports_path
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -48,7 +48,7 @@ Rails.application.routes.draw do
|
||||
|
||||
resources :cost_reports, except: :create do
|
||||
collection do
|
||||
match :index, via: %i[get post]
|
||||
match :index, via: %i[get post], as: :global
|
||||
post :save_as, action: :create
|
||||
get :drill_down
|
||||
match :available_values, via: %i[get post]
|
||||
|
||||
@@ -11,7 +11,7 @@ end %>
|
||||
<% header.with_title { t("external_file_storages") } %>
|
||||
<% header.with_description { t("storages.page_titles.file_storages.subtitle") } %>
|
||||
<% header.with_breadcrumbs([{ href: admin_index_path, text: t("label_administration") },
|
||||
{ href: admin_settings_storages_path, text: t("project_module_storages") },
|
||||
{ href: admin_settings_storages_path, text: t("project_module_storages"), skip_for_mobile: true },
|
||||
t("external_file_storages")]) %>
|
||||
<% end %>
|
||||
|
||||
|
||||
@@ -32,9 +32,10 @@ See COPYRIGHT and LICENSE files for more details.
|
||||
render(Primer::OpenProject::PageHeader.new) do |header|
|
||||
header.with_title { t("team_planner.label_new_team_planner") }
|
||||
header.with_breadcrumbs(
|
||||
[*([href: home_path, text: organization_name] unless @project),
|
||||
*([href: project_overview_path(@project.id), text: @project.name] if @project),
|
||||
t("team_planner.label_new_team_planner")]
|
||||
[
|
||||
({ href: project_overview_path(@project.id), text: @project.name} if @project),
|
||||
t("team_planner.label_new_team_planner")
|
||||
].compact
|
||||
)
|
||||
end
|
||||
%>
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
render Primer::OpenProject::PageHeader.new do |header|
|
||||
header.with_title { t("team_planner.label_team_planner_plural") }
|
||||
header.with_breadcrumbs(
|
||||
[{ href: home_path, text: organization_name },
|
||||
t("team_planner.label_team_planner_plural")]
|
||||
[t("team_planner.label_team_planner_plural")]
|
||||
)
|
||||
end
|
||||
%>
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
# 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"
|
||||
|
||||
RSpec.describe "Breadcrumbs (#63777)", :js do
|
||||
let(:user) { create(:admin) }
|
||||
let(:project) { create(:project) }
|
||||
|
||||
before do
|
||||
login_as user
|
||||
end
|
||||
|
||||
context "when being on an index page which is not the home screen" do
|
||||
it "does not create a loop in the mobile back links" do
|
||||
visit projects_path
|
||||
|
||||
within ".PageHeader-breadcrumbs" do
|
||||
expect(page).to have_link href: "#", text: "Active projects", aria: { current: "page" }
|
||||
expect(page).to have_link href: "/projects", text: "Projects"
|
||||
expect(page).to have_link href: "/", text: "OpenProject"
|
||||
end
|
||||
|
||||
expect(page).to have_link href: "/", text: "OpenProject", class: "PageHeader-parentLink", visible: :hidden
|
||||
end
|
||||
end
|
||||
|
||||
context "when being on an non-index page" do
|
||||
it "does show the index page as mobile back link" do
|
||||
visit projects_path({ query_id: "my" })
|
||||
|
||||
within ".PageHeader-breadcrumbs" do
|
||||
expect(page).to have_link href: "#", text: "My projects", aria: { current: "page" }
|
||||
expect(page).to have_link href: "/projects", text: "Projects"
|
||||
expect(page).to have_link href: "/", text: "OpenProject"
|
||||
end
|
||||
|
||||
expect(page).to have_link href: "/projects", text: "Projects", class: "PageHeader-parentLink", visible: :hidden
|
||||
end
|
||||
end
|
||||
|
||||
context "when being on the home screen" do
|
||||
it "does not display a (mobile) back link" do
|
||||
visit "/"
|
||||
|
||||
within ".PageHeader-breadcrumbs" do
|
||||
expect(page).to have_link href: "#", text: "Home", aria: { current: "page" }
|
||||
expect(page).to have_link href: "/", text: "OpenProject"
|
||||
|
||||
expect(page).to have_no_css ".PageHeader-parentLink"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user