stable

Clone or download

Read-only

fix: aggregated projects popover is now reachable

When a project has more than 5 aggregated projects, those are displayed in a popover instead of the sidebar so that the latter is not cluttered. If user wants to click on one of the aggregated projects, then the popover hides as soon as the user tries to reach it, which is pretty frustrating. This comes from the fact that when popover are built on a `hover` trigger, they are displayed only when the mouse is over the trigger element. As soon as the mouse leaves the trigger, the popover is hidden. This may be fine for popover that contains only text, but when it contains interactions elements like links it is not usable at all. The current proposal is to delay the close of the popover in order to let time to the user to reach the popover content. Basically the scenario is the following: * If mouse leaves the trigger, then we start a timeout. * When the timeout ends, we close the popover. * If, before the timeout ends, the mouse enters the popover content, then we stop the timeout, and restart it whenever the mouse leaves the popover. * If, before the timeout ends, the display of another popover is triggered, then we stop the timout and close the previous popover. This timeout has a fixed duration for now. By wild guess we estimate that 200ms is enough to reach the popover content. Furthermore since the issue is common to every popovers in Tuleap we don't need to make it configurable per popover. Now that we discussed about the general approach of this contribution, let's talk about the fun stuff 🤯 The introduction of this timeout highlighted a flaw in the popovers closing management. Whenever we wanted to close every open popovers, we searched for open ones with `querySelectorAll(".tlp-popover-shown")`. The issue is that since the sidebar is a custom element, `querySelectorAll` cannot traverse its shadow dom to retrieve the open popovers. In order to do that we have to explicitely target the `shadowRoot` inside the custom element: ```javascript [ document.querySelector('.tlp-popover-shown'), document.getElementsByTagName('tuleap-project-sidebar')[0].shadowRoot.querySelector('.tlp-popover-shown') ] // Array [ // null, (😭) // div#project-sidebar-linked-projects-popover.tlp-popover.project-sidebar-linked-projects-popover.project-sidebar-linked-projects-popover-nb-max-exceeded.tlp-popover-shown // ] ``` Since `@tuleap/tlp-popovers`, should know nothing (like Jon Snow) about various custom elements used in the page, we had to find another way to close those open popovers. That is why we now use a `CustomEvent`. Instead of searching for open popovers, we reverse the behavior by letting popovers close themselves as soon as the receive a force-close event. "Tell, don't ask" sort of. BTW now the links in the popovers are real links. To test: How to test: * have a project with many linked project (nb > config) * hover the "nb aggregated projects" in the sidebar * popover is displayed * you can hover subproject in popover and click on them * leave the project list * popover is closed Part of story #34009: see aggregated & parents projects Change-Id: Ib3b08b73946c0035ba634bf76a5782981b6c7dd5

Modified Files

Name
M lib/frontend/project-sidebar-internal/src/Header/LinkedProjects.vue +5 −2 Go to diff View file
M lib/frontend/project-sidebar-internal/src/Header/__snapshots__/LinkedProjects.test.ts.snap +122 −50 Go to diff View file
M lib/frontend/project-sidebar-internal/src/project-sidebar-example-config.ts +30 −0 Go to diff View file
M lib/frontend/project-sidebar/CHANGELOG.md +3 −2 Go to diff View file
M lib/frontend/tlp-popovers/src/popovers.test.ts +60 −79 Go to diff View file
M lib/frontend/tlp-popovers/src/popovers.ts +73 −6 Go to diff View file