From be8954676120a0fca322530a2aed57fb3ea07cf7 Mon Sep 17 00:00:00 2001 From: Mathieu Suen Date: Tue, 31 Jan 2023 10:43:07 +0100 Subject: [PATCH] SONAR-18068 Page does not identify purpose of page --- .../components/ProfileContainer.tsx | 18 ++++------ .../__tests__/ProfileContainer-test.tsx | 34 +++++++++++-------- .../details/ProfileHeader.tsx | 15 ++++++++ .../main/js/apps/quality-profiles/routes.tsx | 11 ++++-- .../resources/org/sonar/l10n/core.properties | 2 ++ 5 files changed, 50 insertions(+), 30 deletions(-) diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileContainer.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileContainer.tsx index 275deded89f..ddc968d65a0 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileContainer.tsx +++ b/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileContainer.tsx @@ -22,16 +22,17 @@ import { Helmet } from 'react-helmet-async'; import { Outlet, useSearchParams } from 'react-router-dom'; import { useLocation } from '../../../components/hoc/withRouter'; import ProfileHeader from '../details/ProfileHeader'; -import { QualityProfilesContextProps, withQualityProfilesContext } from '../qualityProfilesContext'; +import { useQualityProfilesContext } from '../qualityProfilesContext'; import ProfileNotFound from './ProfileNotFound'; -export function ProfileContainer(props: QualityProfilesContextProps) { +export default function ProfileContainer() { const [_, setSearchParams] = useSearchParams(); const location = useLocation(); const { key, language, name } = location.query; - const { profiles } = props; + const context = useQualityProfilesContext(); + const { profiles } = context; // try to find a quality profile with the given key // if managed to find one, redirect to a new version @@ -55,22 +56,15 @@ export function ProfileContainer(props: QualityProfilesContextProps) { return <ProfileNotFound />; } - const context: QualityProfilesContextProps = { - profile, - ...props, - }; - return ( <div id="quality-profile"> <Helmet defer={false} title={profile.name} /> <ProfileHeader profile={profile} isComparable={filteredProfiles.length > 1} - updateProfiles={props.updateProfiles} + updateProfiles={context.updateProfiles} /> - <Outlet context={context} /> + <Outlet context={{ profile, ...context }} /> </div> ); } - -export default withQualityProfilesContext(ProfileContainer); diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/components/__tests__/ProfileContainer-test.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/components/__tests__/ProfileContainer-test.tsx index b84b65c8a4b..b771e089918 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/components/__tests__/ProfileContainer-test.tsx +++ b/server/sonar-web/src/main/js/apps/quality-profiles/components/__tests__/ProfileContainer-test.tsx @@ -20,14 +20,14 @@ import { render, screen } from '@testing-library/react'; import * as React from 'react'; import { HelmetProvider } from 'react-helmet-async'; -import { MemoryRouter, Route, Routes } from 'react-router-dom'; +import { MemoryRouter, Outlet, Route, Routes } from 'react-router-dom'; import { mockQualityProfile } from '../../../../helpers/testMocks'; import { QualityProfilesContextProps, withQualityProfilesContext, } from '../../qualityProfilesContext'; import { Profile } from '../../types'; -import { ProfileContainer } from '../ProfileContainer'; +import ProfileContainer from '../ProfileContainer'; it('should render the header and child', () => { const targetProfile = mockQualityProfile({ name: 'profile1' }); @@ -69,23 +69,27 @@ function Child(props: { profile?: Profile }) { const WrappedChild = withQualityProfilesContext(Child); function renderProfileContainer(path: string, overrides: Partial<QualityProfilesContextProps>) { + function ProfileOutlet(props: Partial<QualityProfilesContextProps>) { + const context = { + actions: {}, + exporters: [], + languages: [], + profiles: [], + updateProfiles: jest.fn(), + ...props, + }; + + return <Outlet context={context} />; + } + return render( <HelmetProvider context={{}}> <MemoryRouter initialEntries={[path]}> <Routes> - <Route - element={ - <ProfileContainer - actions={{}} - exporters={[]} - languages={[]} - profiles={[]} - updateProfiles={jest.fn()} - {...overrides} - /> - } - > - <Route path="*" element={<WrappedChild />} /> + <Route element={<ProfileOutlet {...overrides} />}> + <Route element={<ProfileContainer />}> + <Route path="*" element={<WrappedChild />} /> + </Route> </Route> </Routes> </MemoryRouter> diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileHeader.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileHeader.tsx index c4b3f217a78..2ca6f42e977 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileHeader.tsx +++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileHeader.tsx @@ -18,6 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import * as React from 'react'; +import { Helmet } from 'react-helmet-async'; import { FormattedMessage } from 'react-intl'; import { NavLink } from 'react-router-dom'; import Link from '../../../components/common/Link'; @@ -31,6 +32,7 @@ import BuiltInQualityProfileBadge from '../components/BuiltInQualityProfileBadge import ProfileActions from '../components/ProfileActions'; import ProfileLink from '../components/ProfileLink'; import { PROFILE_PATH } from '../constants'; +import { QualityProfilePath } from '../routes'; import { Profile } from '../types'; import { getProfileChangelogPath, @@ -47,9 +49,22 @@ interface Props { export default function ProfileHeader(props: Props) { const { profile, isComparable, updateProfiles } = props; const location = useLocation(); + const isComparePage = location.pathname.endsWith(`/${QualityProfilePath.COMPARE}`); + const isChangeLogPage = location.pathname.endsWith(`/${QualityProfilePath.CHANGELOG}`); return ( <div className="page-header quality-profile-header"> + {(isComparePage || isChangeLogPage) && ( + <Helmet + defer={false} + title={translateWithParameters( + isChangeLogPage + ? 'quality_profiles.page_title_changelog_x' + : 'quality_profiles.page_title_compare_x', + profile.name + )} + /> + )} <div className="note spacer-bottom"> <NavLink end={true} to={PROFILE_PATH}> {translate('quality_profiles.page')} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/routes.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/routes.tsx index 3b7862e10e0..cf20d65f63c 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/routes.tsx +++ b/server/sonar-web/src/main/js/apps/quality-profiles/routes.tsx @@ -26,13 +26,18 @@ import QualityProfilesApp from './components/QualityProfilesApp'; import ProfileDetails from './details/ProfileDetails'; import HomeContainer from './home/HomeContainer'; +export enum QualityProfilePath { + SHOW = 'show', + CHANGELOG = 'changelog', + COMPARE = 'compare', +} const routes = () => ( <Route path="profiles" element={<QualityProfilesApp />}> <Route index={true} element={<HomeContainer />} /> <Route element={<ProfileContainer />}> - <Route path="show" element={<ProfileDetails />} /> - <Route path="changelog" element={<ChangelogContainer />} /> - <Route path="compare" element={<ComparisonContainer />} /> + <Route path={QualityProfilePath.SHOW} element={<ProfileDetails />} /> + <Route path={QualityProfilePath.CHANGELOG} element={<ChangelogContainer />} /> + <Route path={QualityProfilePath.COMPARE} element={<ComparisonContainer />} /> </Route> </Route> ); diff --git a/sonar-core/src/main/resources/org/sonar/l10n/core.properties b/sonar-core/src/main/resources/org/sonar/l10n/core.properties index 959e8225dfc..815aa6c421e 100644 --- a/sonar-core/src/main/resources/org/sonar/l10n/core.properties +++ b/sonar-core/src/main/resources/org/sonar/l10n/core.properties @@ -1653,6 +1653,8 @@ project.info.see_more_info_on_x_locs=See more information on your {0} lines of c # #------------------------------------------------------------------------------ +quality_profiles.page_title_changelog_x={0} - Quality profile changelog +quality_profiles.page_title_compare_x={0} - Quality profile comparaison quality_profiles.new_profile=New Quality Profile quality_profiles.compare_with=Compare with quality_profiles.filter_by=Filter profiles by -- 2.39.5