Skip to content

Commit 2efbfe8

Browse files
JeyffreyHEYGUL
authored andcommitted
feat(mon-pix): close user logged menu on link mouse click
1 parent 71ae1da commit 2efbfe8

3 files changed

Lines changed: 91 additions & 32 deletions

File tree

mon-pix/app/components/user-logged-menu.gjs

Lines changed: 40 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,46 @@ import t from 'ember-intl/helpers/t';
1010
import onKey from 'ember-keyboard/modifiers/on-key';
1111

1212
export default class UserLoggedMenu extends Component {
13+
@service currentUser;
14+
15+
@tracked canDisplayMenu = false;
16+
17+
get displayedIdentifier() {
18+
return this.currentUser.user.email ? this.currentUser.user.email : this.currentUser.user.username;
19+
}
20+
21+
get showMyTestsLink() {
22+
return this.currentUser.user.hasAssessmentParticipations;
23+
}
24+
25+
@action
26+
toggleUserMenu() {
27+
this.canDisplayMenu = !this.canDisplayMenu;
28+
}
29+
30+
@action
31+
closeMenu() {
32+
this.canDisplayMenu = false;
33+
}
34+
35+
@action
36+
handleTab() {
37+
/* `setTimeout(..., 0)` is used to wait the next browser rendering and get the new focused element */
38+
setTimeout(() => {
39+
if (!document.activeElement.classList.contains('logged-user-menu__link')) {
40+
this.closeMenu();
41+
}
42+
}, 0);
43+
}
44+
45+
@action
46+
closeMenuOnPointerClick(event) {
47+
if (!event.pointerType || !event.target.closest('.logged-user-menu__link')) return;
48+
this.closeMenu();
49+
}
50+
1351
<template>
52+
{{! template-lint-disable no-invalid-interactive }}
1453
<div class="logged-user-details">
1554
{{#if this.currentUser.user}}
1655
<button
@@ -31,6 +70,7 @@ export default class UserLoggedMenu extends Component {
3170
{{onClickOutside this.closeMenu}}
3271
{{onKey "Escape" this.closeMenu}}
3372
{{onKey "Tab" this.handleTab}}
73+
{{on "click" this.closeMenuOnPointerClick}}
3474
>
3575
<div class="logged-user-menu__details">
3676
<div class="logged-user-menu-details__fullname">{{this.currentUser.user.fullName}}</div>
@@ -75,35 +115,4 @@ export default class UserLoggedMenu extends Component {
75115
{{/if}}
76116
</div>
77117
</template>
78-
@service currentUser;
79-
80-
@tracked canDisplayMenu = false;
81-
82-
get displayedIdentifier() {
83-
return this.currentUser.user.email ? this.currentUser.user.email : this.currentUser.user.username;
84-
}
85-
86-
get showMyTestsLink() {
87-
return this.currentUser.user.hasAssessmentParticipations;
88-
}
89-
90-
@action
91-
toggleUserMenu() {
92-
this.canDisplayMenu = !this.canDisplayMenu;
93-
}
94-
95-
@action
96-
closeMenu() {
97-
this.canDisplayMenu = false;
98-
}
99-
100-
@action
101-
handleTab() {
102-
/* `setTimeout(..., 0)` is used to wait the next browser rendering and get the new focused element */
103-
setTimeout(() => {
104-
if (!document.activeElement.classList.contains('logged-user-menu__link')) {
105-
this.closeMenu();
106-
}
107-
}, 0);
108-
}
109118
}

mon-pix/app/styles/components/_user-logged-menu.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,4 +94,8 @@
9494
text-decoration: none;
9595
background-color: var(--pix-neutral-20);
9696
}
97+
98+
&.active {
99+
font-weight: bold;
100+
}
97101
}

mon-pix/tests/integration/components/user-logged-menu-test.js

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { render } from '@1024pix/ember-testing-library';
2-
import { click, triggerKeyEvent } from '@ember/test-helpers';
2+
import { click, settled, triggerEvent, triggerKeyEvent } from '@ember/test-helpers';
33
import { hbs } from 'ember-cli-htmlbars';
44
import { t } from 'ember-intl/test-support';
55
import { module, test } from 'qunit';
@@ -167,6 +167,52 @@ module('Integration | Component | user logged menu', function (hooks) {
167167
assert.dom(screen.queryByRole('link', { name: t('navigation.user.account') })).doesNotExist();
168168
});
169169

170+
test('should hide user menu when a link is clicked with a pointer device', async function (assert) {
171+
// given
172+
const screen = await render(hbs`<UserLoggedMenu />`);
173+
const buttonMenu = screen.getByRole('button', {
174+
name: `Hermione ${t('navigation.user-logged-menu.details')}`,
175+
});
176+
await click(buttonMenu);
177+
178+
// when
179+
const link = screen.getByRole('link', { name: t('navigation.main.help') });
180+
link.dispatchEvent(new PointerEvent('click', { bubbles: true, pointerType: 'mouse' }));
181+
await settled();
182+
183+
// then
184+
assert
185+
.dom(
186+
screen.getByRole('button', {
187+
name: `Hermione ${t('navigation.user-logged-menu.details')}`,
188+
expanded: false,
189+
}),
190+
)
191+
.exists();
192+
});
193+
194+
test('should keep user menu open when a link is activated with the keyboard', async function (assert) {
195+
// given
196+
const screen = await render(hbs`<UserLoggedMenu />`);
197+
const buttonMenu = screen.getByRole('button', {
198+
name: `Hermione ${t('navigation.user-logged-menu.details')}`,
199+
});
200+
await click(buttonMenu);
201+
202+
// when
203+
await triggerEvent(screen.getByRole('link', { name: t('navigation.main.help') }), 'click', { detail: 0 });
204+
205+
// then
206+
assert
207+
.dom(
208+
screen.getByRole('button', {
209+
name: `Hermione ${t('navigation.user-logged-menu.details')}`,
210+
expanded: true,
211+
}),
212+
)
213+
.exists();
214+
});
215+
170216
module('Link to "My tests"', function () {
171217
module('when user has at least one participation', function (hooks) {
172218
hooks.beforeEach(function () {

0 commit comments

Comments
 (0)