• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

EcrituresNumeriques / stylo / 18525052247

15 Oct 2025 09:57AM UTC coverage: 39.154% (-0.5%) from 39.607%
18525052247

push

github

web-flow
feat: mémorise le workspace sélectionné depuis le menu de navigation (#1666)

Co-authored-by: Thomas Parisot <thom4parisot@users.noreply.github.com>

602 of 851 branches covered (70.74%)

Branch coverage included in aggregate %.

34 of 47 new or added lines in 5 files covered. (72.34%)

88 existing lines in 5 files now uncovered.

5927 of 15824 relevant lines covered (37.46%)

2.55 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/front/src/components/Header.jsx
1
import clsx from 'clsx'
×
2
import { Menu } from 'lucide-react'
×
NEW
3
import React, { useCallback, useMemo } from 'react'
×
4
import { useTranslation } from 'react-i18next'
×
5
import { Link, NavLink, useLocation, useRouteLoaderData } from 'react-router'
×
6

7
import logoContent from '/images/logo.svg?inline'
×
8

9
import useComponentVisible from '../hooks/componentVisible.js'
×
10
import { useActiveWorkspaceId } from '../hooks/workspace.js'
×
11

12
import LanguagesMenu from './header/LanguagesMenu.jsx'
×
13
import UserMenu from './header/UserMenu.jsx'
×
14
import WorkspacesMenu from './workspace/WorkspacesMenu.jsx'
×
15

16
import styles from './header.module.scss'
×
NEW
17
import { useDispatch } from 'react-redux'
×
18

19
export default function Header() {
×
20
  const { t } = useTranslation()
×
21
  const activeWorkspaceId = useActiveWorkspaceId()
×
NEW
22
  const dispatch = useDispatch()
×
23
  const { user } = useRouteLoaderData('app')
×
24
  const location = useLocation()
×
25
  const activeTool = location.pathname.includes('/corpus')
×
26
    ? 'corpus'
×
27
    : 'articles'
×
28
  const userId = user?._id
×
29
  const baseUrl = useMemo(
×
30
    () => (activeWorkspaceId ? `/workspaces/${activeWorkspaceId}` : ''),
×
31
    [activeWorkspaceId]
×
32
  )
×
33
  const {
×
34
    ref: workspacesRef,
×
35
    isComponentVisible: areWorkspacesVisible,
×
36
    toggleComponentIsVisible: toggleWorkspaces,
×
37
  } = useComponentVisible(false, 'workspaces')
×
38
  const {
×
39
    ref: toolsRef,
×
40
    isComponentVisible: areToolsVisible,
×
41
    toggleComponentIsVisible: toggleTools,
×
42
  } = useComponentVisible(false, 'tools')
×
43

NEW
44
  const resetWorkspaceId = useCallback(() => {
×
NEW
45
    dispatch({ type: 'SET_USER_PREFERENCES', key: 'workspaceId', value: null })
×
NEW
46
  }, [])
×
47

48
  return (
×
49
    <header className={styles.header} role="banner">
×
50
      <div className={styles.container}>
×
51
        <NavLink to="/" rel="home"  className={styles.logo}>
×
52
          <img src={logoContent} alt="Stylo" aria-hidden />
×
53
          <span className="sr-only">{t('header.home')}</span>
×
54
        </NavLink>
×
55

56
        {userId && (
×
57
          <nav
×
58
            role="navigation"
×
59
            id="main-navigation"
×
60
            ref={toolsRef}
×
61
            className={styles.navigation}
×
62
            aria-label={t('header.mainMenu.list')}
×
63
            aria-description={t('header.mainMenu.description')}
×
64
          >
65
            <button
×
66
              className={styles.menuButton}
×
67
              aria-controls="app-menu"
×
68
              aria-pressed={areToolsVisible}
×
69
              onClick={toggleTools}
×
70
            >
71
              <Menu className="icon" aria-hidden />
×
72
              {t('header.mainMenu.button')}
×
73
            </button>
×
74

75
            <div
×
76
              className={clsx(areToolsVisible && styles.menuLinksMobileVisible)}
×
77
              id="app-menu"
×
78
            >
79
              <ul
×
80
                className={styles.menuLinks}
×
81
                aria-label={t('header.mainMenu.list')}
×
82
              >
83
                <li hidden={!userId}>
×
84
                  <NavLink to={`${baseUrl}/articles`} prefetch="intent">
×
85
                    {t('header.mainMenu.articles')}
×
86
                  </NavLink>
×
87
                </li>
×
88
                <li hidden={!userId}>
×
89
                  <NavLink to={`${baseUrl}/corpus`}>
×
90
                    {t('header.mainMenu.corpus')}
×
91
                  </NavLink>
×
92
                </li>
×
93
                <li
×
94
                  hidden={!userId}
×
95
                  ref={workspacesRef}
×
96
                  className={styles.toggleMenu}
×
97
                >
98
                  <button
×
99
                    aria-controls="header-workspaces-list"
×
100
                    aria-expanded={areWorkspacesVisible}
×
101
                    onClick={toggleWorkspaces}
×
102
                  >
103
                    {t('header.mainMenu.workspaces')}
×
104
                  </button>
×
105

106
                  <div
×
107
                    className={styles.toggleMenuContainer}
×
108
                    id="header-workspaces-list"
×
109
                    hidden={!areWorkspacesVisible}
×
110
                  >
111
                    <ul
×
112
                      className={styles.toggleMenuList}
×
113
                      aria-label={t('header.mainMenu.workspaces.list')}
×
114
                    >
115
                      <li>
×
116
                        <Link
×
117
                          to={`/${activeTool}`}
×
NEW
118
                          onClick={resetWorkspaceId}
×
UNCOV
119
                          aria-current={!activeWorkspaceId ? 'page' : false}
×
120
                        >
121
                          <span
×
122
                            className={styles.chip}
×
123
                            style={{ backgroundColor: '#ccc' }}
×
124
                          />
×
125
                          {t('workspace.myspace')}
×
126
                        </Link>
×
127
                      </li>
×
128

129
                      <WorkspacesMenu activeTool={activeTool} />
×
130

131
                      <li>
×
132
                        <NavLink to={`/workspaces`} end>
×
133
                          {t('workspace.all')}
×
134
                        </NavLink>
×
135
                      </li>
×
136
                    </ul>
×
137
                  </div>
×
138
                </li>
×
139
              </ul>
×
140
            </div>
×
141
          </nav>
×
142
        )}
143

144
        <UserMenu />
×
145
        <LanguagesMenu />
×
146
      </div>
×
147
    </header>
×
148
  )
149
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc