Skip to content

Commit

Permalink
Merge pull request #15604 from opf/bug/55024-project-overview-headers…
Browse files Browse the repository at this point in the history
…-stimulus-approach

[#55024] Project overview headers are showing on work package view
  • Loading branch information
dombesz committed May 17, 2024
2 parents 17f0d33 + 52c6db4 commit 2f19591
Show file tree
Hide file tree
Showing 10 changed files with 147 additions and 15 deletions.
23 changes: 23 additions & 0 deletions frontend/src/app/core/routing/openproject.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,29 @@ export function initializeUiRouterListeners(injector:Injector) {
(transition) => redirectToMobileAlternative(transition),
);

// Fire an event when navigating to a different module. This event then can be detected in
// the non-angular parts of the application. A usecase for this can be found in the
// overview-header.controllers.ts
// See https://community.openproject.org/wp/55024 for details.
$transitions.onBefore(
{},
(transition:Transition) => {
const fromState = transition.from();
const toState = transition.to();
if (
!!fromState.name
&& !!toState.name
&& fromState.name?.split('.')[0] !== toState.name?.split('.')[0]
) {
window.dispatchEvent(new CustomEvent('angular:router:module-changed', {
detail: toState.name?.split('.')[0],
}));
}

return true;
},
);

// Apply classes from bodyClasses in each state definition
// This was defined as onEnter, onExit functions in each state before
// but since AOT doesn't allow anonymous functions, we can't re-use them now.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* -- copyright
* OpenProject is an open source project management software.
* Copyright (C) 2023 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.
* ++
*/

import { Controller } from '@hotwired/stimulus';

export default class OverviewHeaderController extends Controller {
connect() {
window.addEventListener('angular:router:module-changed', this.toggleHeaderVisibility);
}

disconnect() {
window.removeEventListener('angular:router:module-changed', this.toggleHeaderVisibility);
}

toggleHeaderVisibility = (event:CustomEvent) => {
const name = event.detail as string;
const element = this.element as HTMLElement;

if (name === 'overview') {
element.classList.remove('d-none');
} else {
element.classList.add('d-none');
}
};
}
9 changes: 6 additions & 3 deletions lib/redmine/menu_manager/menu_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ def render_wrapped_menu_parent_node(node, project)
html_id = node.html_options[:id] || node.name
content_tag(:div, class: "main-item-wrapper", id: "#{html_id}-wrapper") do
concat render_single_menu_node(node, project)
concat render_menu_toggler
concat render_menu_toggler(node.name)
end
end

Expand All @@ -163,11 +163,14 @@ def render_wrapped_single_node(node, project)
end
end

def render_menu_toggler
def render_menu_toggler(node_name)
content_tag(:button,
class: "toggler main-menu-toggler",
type: :button,
data: { action: "menus--main#descend" }) do
data: {
action: "menus--main#descend",
test_selector: "main-menu-toggler--#{node_name}"
}) do
render(Primer::Beta::Octicon.new("arrow-right", size: :small))
end
end
Expand Down
3 changes: 1 addition & 2 deletions modules/boards/spec/features/board_navigation_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,7 @@
with_settings: { notifications_polling_interval: 1_000 } do
visit project_path(project)

item = page.find('#menu-sidebar li[data-name="boards"]', wait: 10)
item.find(".toggler").click
page.find_test_selector("main-menu-toggler--boards", wait: 10).click

subitem = page.find_test_selector("op-sidemenu--item-action--Myboard", wait: 10)
# Ends with boards due to lazy route
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@

# Navigate to the WP module
find(".main-menu--arrow-left-to-project").click
find("#main-menu-work-packages-wrapper .main-menu-toggler").click
page.find_test_selector("main-menu-toggler--work_packages").click

# Select other query
query_menu.select query
Expand All @@ -128,7 +128,7 @@

# Navigate to the Gantt module agin
find(".main-menu--arrow-left-to-project").click
find("#main-menu-gantt-wrapper .main-menu-toggler").click
page.find_test_selector("main-menu-toggler--gantt").click

# Select first query again
query_menu.click_item query_tl.name
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@
<% end -%>
<%=
render(Primer::OpenProject::PageHeader.new(data: { turbo: true })) do |header|
render(Primer::OpenProject::PageHeader.new(
data: {
'controller': 'overview-header',
'application-target': 'dynamic',
turbo: true
}
)) do |header|
header.with_title(variant: :medium) { t("overviews.label") }
header.with_breadcrumbs(
[
Expand Down
49 changes: 49 additions & 0 deletions modules/overviews/spec/features/navigation_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,53 @@
.to have_content("Overview")
end
end

context "as user with permissions" do
let(:project) { create(:project, enabled_module_names: %i[work_package_tracking]) }
let(:user) { create(:admin) }
let(:query) do
create(:query_with_view_work_packages_table,
project:,
user:,
name: "My important Query")
end

before do
query
login_as user
end

it "can navigate to other modules (regression #55024)" do
visit project_overview_path(project.id)

# Expect page to be loaded
within "#content" do
expect(page).to have_content("Overview")
end

# Navigate to the WP module
page.find_test_selector("main-menu-toggler--work_packages").click

# Click on a saved query
page.find_test_selector("op-sidemenu--item-action--MyimportantQuery", wait: 10).click

loading_indicator_saveguard

within "#content" do
# Expect the query content to be shown
expect(page).to have_field("editable-toolbar-title", with: query.name)

# Expect no page header of the Overview to be shown any more
expect(page).to have_no_content("Overview")
end

# Navigate back to the Overview page
page.execute_script("window.history.back()")

# Expect page to be loaded
within "#content" do
expect(page).to have_content("Overview")
end
end
end
end
4 changes: 2 additions & 2 deletions modules/storages/spec/features/storages_module_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@
context "when user has manage_storages_in_project permission" do
it "must show the page and storage menu entry" do
visit project_path(project)
find("button.toggler.main-menu-toggler").click # opens project setting menu
page.find_test_selector("main-menu-toggler--settings").click # opens project setting menu

within "#menu-sidebar" do
expect(page).to have_text(I18n.t(:project_module_storages))
Expand All @@ -164,7 +164,7 @@

it "must not show the page and storage menu entry" do
visit project_path(project)
find("button.toggler.main-menu-toggler").click # opens project setting menu
page.find_test_selector("main-menu-toggler--settings").click # opens project setting menu

within "#menu-sidebar" do
expect(page).to have_no_text(I18n.t(:project_module_storages))
Expand Down
2 changes: 1 addition & 1 deletion spec/features/work_packages/navigation_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@
it "access the work package views directly from a non-angular view" do
visit project_path(project)

find("#main-menu-work-packages ~ .toggler").click
page.find_test_selector("main-menu-toggler--work_packages").click
expect(page).to have_css(".op-view-select--search-results")
find(".op-sidemenu--item-action", text: query.name).click

Expand Down
8 changes: 4 additions & 4 deletions spec/lib/redmine/menu_manager/menu_helper_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ def @controller.current_menu_item
<span class="ellipsis">Parent node</span>
</span>
</a>
<button class="toggler main-menu-toggler" type="button" data-action="menus--main#descend">
<button class="toggler main-menu-toggler" type="button" data-action="menus--main#descend" data-test-selector="main-menu-toggler--parent_node">
<svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-arrow-right">
<path d="M8.22 2.97a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l2.97-2.97H3.75a.75.75 0 0 1 0-1.5h7.44L8.22 4.03a.75.75 0 0 1 0-1.06Z"></path>
</svg>
Expand Down Expand Up @@ -218,7 +218,7 @@ def @controller.current_menu_item
<span class="ellipsis">Parent node</span>
</span>
</a>
<button class="toggler main-menu-toggler" type="button" data-action="menus--main#descend">
<button class="toggler main-menu-toggler" type="button" data-action="menus--main#descend" data-test-selector="main-menu-toggler--parent_node">
<svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-arrow-right">
<path d="M8.22 2.97a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l2.97-2.97H3.75a.75.75 0 0 1 0-1.5h7.44L8.22 4.03a.75.75 0 0 1 0-1.06Z"></path>
</svg>
Expand Down Expand Up @@ -296,7 +296,7 @@ def @controller.current_menu_item
<span class="ellipsis">Parent node</span>
</span>
</a>
<button class="toggler main-menu-toggler" type="button" data-action="menus--main#descend">
<button class="toggler main-menu-toggler" type="button" data-action="menus--main#descend" data-test-selector="main-menu-toggler--parent_node">
<svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-arrow-right">
<path d="M8.22 2.97a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l2.97-2.97H3.75a.75.75 0 0 1 0-1.5h7.44L8.22 4.03a.75.75 0 0 1 0-1.06Z"></path>
</svg>
Expand All @@ -320,7 +320,7 @@ def @controller.current_menu_item
<span class="ellipsis">Child node</span>
</span>
</a>
<button class="toggler main-menu-toggler" type="button" data-action="menus--main#descend">
<button class="toggler main-menu-toggler" type="button" data-action="menus--main#descend" data-test-selector="main-menu-toggler--child_node">
<svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-arrow-right">
<path d="M8.22 2.97a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l2.97-2.97H3.75a.75.75 0 0 1 0-1.5h7.44L8.22 4.03a.75.75 0 0 1 0-1.06Z"></path>
</svg>
Expand Down

0 comments on commit 2f19591

Please sign in to comment.