Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions app/views/warning_bar/_warning_bar.html.erb
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<% if show_warning_bar? %>
<div class="warning-bar--wrapper">
<%= render partial: "warning_bar/host_and_protocol_mismatch" if render_host_and_protocol_mismatch? %>
<%= render partial: "warning_bar/pending_migrations" if render_pending_migrations_warning? %>
<%= render partial: "warning_bar/unsupported_browser" if unsupported_browser? %>
<%= render partial: "warning_bar/missing_wp_edit_role_workflows" if render_workflow_missing_warning? %>
<div class="warning-bar--wrapper" data-controller="warning-bar">
<% if show_warning_bar? %>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not a big fan of running a resizeObserver constantly even if the bar is not shown at all. Why did you move the div which registers the controller outside the check?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because show_warning_bar? will not be the only condition. In the PR it will render the sudo banner inside this as well. So the wrapper is always present, just without any content.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A resize observer is not really "running" anything. It is invoked when a resize happens, not constantly running a loop and polling for changes.

<%= render partial: "warning_bar/host_and_protocol_mismatch" if render_host_and_protocol_mismatch? %>
<%= render partial: "warning_bar/pending_migrations" if render_pending_migrations_warning? %>
<%= render partial: "warning_bar/unsupported_browser" if unsupported_browser? %>
<%= render partial: "warning_bar/missing_wp_edit_role_workflows" if render_workflow_missing_warning? %>
<% end %>
</div>
<% end %>
2 changes: 1 addition & 1 deletion frontend/src/global_styles/layout/_base.sass
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
margin: 0 0 0 0
padding: 0
// Needed for Safari
height: calc(100dvh - var(--header-height))
height: calc(100dvh - var(--header-height) - var(--warning-bar-height, 0px))
overflow-y: auto
overflow-x: hidden
background-color: var(--body-background)
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/global_styles/layout/_base_mobile.sass
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
#main,
#content-wrapper,
#main-menu #menu-sidebar
height: 100dvh
height: calc(100dvh - var(--warning-bar-height, 0px))

#main .content-overlay
top: 0 !important
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/global_styles/layout/_main_menu.sass
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ $arrow-left-width: 36px
display: flex
flex-direction: column
+allow-vertical-scrolling
height: calc(100dvh - var(--header-height))
height: calc(100dvh - var(--header-height) - var(--warning-bar-height, 0px))
position: relative
@include styled-scroll-bar
padding: 0 var(--main-menu-x-spacing) var(--main-menu-x-spacing) var(--main-menu-x-spacing)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
//-- 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, see <https://www.gnu.org/licenses/>.
//
// See COPYRIGHT and LICENSE files for more details.
//++

import { waitFor } from '@testing-library/dom';

import WarningBarController from './warning-bar.controller';
import { setupStimulusTest, type StimulusTestContext } from 'core-stimulus/test-helpers';

describe('WarningBarController', () => {
let ctx:StimulusTestContext;

const warningBarHeight = () => document.documentElement.style.getPropertyValue('--warning-bar-height');

beforeEach(async () => {
ctx = await setupStimulusTest({
controllers: { 'warning-bar': WarningBarController },
});
});

afterEach(() => ctx.dispose());

it('publishes the height of the bar', async () => {
await ctx.mount(`
<div data-controller="warning-bar">
<div style="height: 42px"></div>
</div>
`);

await waitFor(() => {
expect(warningBarHeight()).toBe('42px');
});
});

it('publishes the new height when the bar grows', async () => {
await ctx.mount(`
<div data-controller="warning-bar">
<div id="banner" style="height: 42px"></div>
</div>
`);
await waitFor(() => expect(warningBarHeight()).toBe('42px'));

document.getElementById('banner')!.style.height = '80px';

await waitFor(() => {
expect(warningBarHeight()).toBe('80px');
});
});

it('publishes no height for an empty bar', async () => {
await ctx.mount('<div data-controller="warning-bar"></div>');

await waitFor(() => {
expect(warningBarHeight()).toBe('0px');
});
});

it('removes the height when the bar is removed', async () => {
await ctx.mount(`
<div data-controller="warning-bar">
<div style="height: 42px"></div>
</div>
`);
await waitFor(() => expect(warningBarHeight()).toBe('42px'));

document.querySelector('[data-controller="warning-bar"]')!.remove();

await waitFor(() => {
expect(warningBarHeight()).toBe('');
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//-- 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, see <https://www.gnu.org/licenses/>.
//
// See COPYRIGHT and LICENSE files for more details.
//++

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

export default class WarningBarController extends Controller<HTMLElement> {
private resizeObserver:ResizeObserver;

connect() {
this.resizeObserver = new ResizeObserver(() => this.publishHeight());
this.resizeObserver.observe(this.element);
}

disconnect() {
this.resizeObserver.disconnect();
document.documentElement.style.removeProperty('--warning-bar-height');
}

private publishHeight() {
document.documentElement.style.setProperty('--warning-bar-height', `${this.element.offsetHeight}px`);
}
}
8 changes: 0 additions & 8 deletions frontend/src/turbo/turbo-global-listeners.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,6 @@ import { isOpenProjectCustomElement } from './openproject-custom-element';

export function addTurboGlobalListeners(target:Document = document, signal?:AbortSignal) {
const runOnRenderAndLoad = () => {
// Add to content if warnings displayed
if (target.querySelector('.warning-bar--item')) {
const content = target.querySelector<HTMLElement>('#content');
if (content) {
content.style.marginBottom = '100px';
}
}

const deviceService:DeviceService = new DeviceService();
// Register scroll handler on mobile header
if (deviceService.isMobile) {
Expand Down
Loading