Bläddra i källkod

SONAR-14368 Add link to tutorial for analyzed projects

tags/8.7.0.41497
Jeremy Davis 3 år sedan
förälder
incheckning
25601fcc5e

+ 5
- 0
server/sonar-web/src/main/js/app/components/nav/component/branch-like/CurrentBranchLike.tsx Visa fil

@@ -106,6 +106,11 @@ export function CurrentBranchLike(props: CurrentBranchLikeProps) {
{
href: '/documentation/analysis/pull-request/',
label: translate('branch_like_navigation.only_one_branch.pr_analysis')
},
{
href: `/tutorials?id=${component.key}`,
label: translate('branch_like_navigation.tutorial_for_ci'),
inPlace: true
}
]}
title={translate('branch_like_navigation.only_one_branch.title')}>

+ 5
- 0
server/sonar-web/src/main/js/app/components/nav/component/branch-like/__tests__/__snapshots__/CurrentBranchLike-test.tsx.snap Visa fil

@@ -199,6 +199,11 @@ exports[`CurrentBranchLikeRenderer should render correctly for project when ther
"href": "/documentation/analysis/pull-request/",
"label": "branch_like_navigation.only_one_branch.pr_analysis",
},
Object {
"href": "/tutorials?id=my-project",
"inPlace": true,
"label": "branch_like_navigation.tutorial_for_ci",
},
]
}
title="branch_like_navigation.only_one_branch.title"

+ 2
- 0
server/sonar-web/src/main/js/app/utils/startReactApp.tsx Visa fil

@@ -59,6 +59,7 @@ import qualityProfilesRoutes from '../../apps/quality-profiles/routes';
import sessionsRoutes from '../../apps/sessions/routes';
import settingsRoutes from '../../apps/settings/routes';
import systemRoutes from '../../apps/system/routes';
import tutorialsRoutes from '../../apps/tutorials/routes';
import usersRoutes from '../../apps/users/routes';
import webAPIRoutes from '../../apps/web-api/routes';
import webhooksRoutes from '../../apps/webhooks/routes';
@@ -189,6 +190,7 @@ function renderComponentRoutes() {
path="project/quality_profiles"
childRoutes={projectQualityProfilesRoutes}
/>
<RouteWithChildRoutes path="tutorials" childRoutes={tutorialsRoutes} />
<Route component={lazyLoadComponent(() => import('../components/ProjectAdminContainer'))}>
<RouteWithChildRoutes path="custom_measures" childRoutes={customMeasuresRoutes} />
<Route

+ 46
- 0
server/sonar-web/src/main/js/apps/tutorials/components/TutorialsApp.tsx Visa fil

@@ -0,0 +1,46 @@
/*
* SonarQube
* Copyright (C) 2009-2021 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
import handleRequiredAuthentication from 'sonar-ui-common/helpers/handleRequiredAuthentication';
import { withCurrentUser } from '../../../components/hoc/withCurrentUser';
import TutorialSelection from '../../../components/tutorials/TutorialSelection';
import { isLoggedIn } from '../../../helpers/users';

export interface TutorialsAppProps {
component: T.Component;
currentUser: T.CurrentUser;
}

export function TutorialsApp(props: TutorialsAppProps) {
const { component, currentUser } = props;

if (!isLoggedIn(currentUser)) {
handleRequiredAuthentication();
return null;
}

return (
<div className="page page-limited">
<TutorialSelection component={component} currentUser={currentUser} />
</div>
);
}

export default withCurrentUser(TutorialsApp);

+ 41
- 0
server/sonar-web/src/main/js/apps/tutorials/components/__tests__/TutorialsApp-test.tsx Visa fil

@@ -0,0 +1,41 @@
/*
* SonarQube
* Copyright (C) 2009-2021 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import { shallow } from 'enzyme';
import * as React from 'react';
import handleRequiredAuthentication from 'sonar-ui-common/helpers/handleRequiredAuthentication';
import { mockComponent, mockCurrentUser, mockLoggedInUser } from '../../../../helpers/testMocks';
import { TutorialsApp, TutorialsAppProps } from '../TutorialsApp';

jest.mock('sonar-ui-common/helpers/handleRequiredAuthentication', () => ({ default: jest.fn() }));

it('should render correctly', () => {
expect(shallowRender()).toMatchSnapshot();
});

it('should redirect if user is not logged in', () => {
shallowRender({ currentUser: mockCurrentUser() });
expect(handleRequiredAuthentication).toHaveBeenCalled();
});

function shallowRender(overrides: Partial<TutorialsAppProps> = {}) {
return shallow(
<TutorialsApp component={mockComponent()} currentUser={mockLoggedInUser()} {...overrides} />
);
}

+ 41
- 0
server/sonar-web/src/main/js/apps/tutorials/components/__tests__/__snapshots__/TutorialsApp-test.tsx.snap Visa fil

@@ -0,0 +1,41 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`should render correctly 1`] = `
<div
className="page page-limited"
>
<withRouter(TutorialSelection)
component={
Object {
"breadcrumbs": Array [],
"key": "my-project",
"name": "MyProject",
"qualifier": "TRK",
"qualityGate": Object {
"isDefault": true,
"key": "30",
"name": "Sonar way",
},
"qualityProfiles": Array [
Object {
"deleted": false,
"key": "my-qp",
"language": "ts",
"name": "Sonar way",
},
],
"tags": Array [],
}
}
currentUser={
Object {
"groups": Array [],
"isLoggedIn": true,
"login": "luke",
"name": "Skywalker",
"scmAccounts": Array [],
}
}
/>
</div>
`;

+ 29
- 0
server/sonar-web/src/main/js/apps/tutorials/routes.ts Visa fil

@@ -0,0 +1,29 @@
/*
* SonarQube
* Copyright (C) 2009-2021 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

import { lazyLoadComponent } from 'sonar-ui-common/components/lazyLoadComponent';

const routes = [
{
indexRoute: { component: lazyLoadComponent(() => import('./components/TutorialsApp')) }
}
];

export default routes;

+ 17
- 10
server/sonar-web/src/main/js/components/common/DocumentationTooltip.tsx Visa fil

@@ -18,6 +18,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
import { Link } from 'react-router';
import HelpTooltip from 'sonar-ui-common/components/controls/HelpTooltip';
import DetachIcon from 'sonar-ui-common/components/icons/DetachIcon';
import { isWebUri } from 'valid-url';
@@ -26,7 +27,7 @@ export interface DocumentationTooltipProps {
children?: React.ReactNode;
className?: string;
content?: React.ReactNode;
links?: Array<{ href: string; label: string }>;
links?: Array<{ href: string; label: string; inPlace?: boolean }>;
title?: string;
}

@@ -50,16 +51,22 @@ export default function DocumentationTooltip(props: DocumentationTooltipProps) {
<>
<hr className="big-spacer-top big-spacer-bottom" />

{links.map(({ href, label }) => (
{links.map(({ href, label, inPlace }) => (
<div className="little-spacer-bottom" key={label}>
<a
className="display-inline-flex-center link-with-icon"
href={href}
rel="noopener noreferrer"
target="_blank">
{isWebUri(href) && <DetachIcon size={14} className="spacer-right" />}
<span>{label}</span>
</a>
{inPlace ? (
<Link to={href}>
<span>{label}</span>
</Link>
) : (
<a
className="display-inline-flex-center link-with-icon"
href={href}
rel="noopener noreferrer"
target="_blank">
{isWebUri(href) && <DetachIcon size={14} className="spacer-right" />}
<span>{label}</span>
</a>
)}
</div>
))}
</>

+ 2
- 1
server/sonar-web/src/main/js/components/common/__tests__/DocumentationTooltip-test.tsx Visa fil

@@ -27,7 +27,8 @@ it('renders correctly', () => {
shallowRender({
links: [
{ href: 'http://link.tosome.place', label: 'external link' },
{ href: '/documentation/guide', label: 'internal link' }
{ href: '/documentation/guide', label: 'internal link' },
{ href: '/projects', label: 'in place', inPlace: true }
]
})
).toMatchSnapshot('with links');

+ 13
- 0
server/sonar-web/src/main/js/components/common/__tests__/__snapshots__/DocumentationTooltip-test.tsx.snap Visa fil

@@ -105,6 +105,19 @@ exports[`renders correctly: with links 1`] = `
</span>
</a>
</div>
<div
className="little-spacer-bottom"
>
<Link
onlyActiveOnIndex={false}
style={Object {}}
to="/projects"
>
<span>
in place
</span>
</Link>
</div>
</React.Fragment>
</div>
}

+ 0
- 1
server/sonar-web/src/main/js/components/tutorials/manual/BuildToolForm.tsx Visa fil

@@ -24,7 +24,6 @@ import RenderOptions from '../components/RenderOptions';
import { BuildTools, ManualTutorialConfig, OSs } from '../types';

interface Props {
component: T.Component;
config?: ManualTutorialConfig;
onDone: (config: ManualTutorialConfig) => void;
}

+ 1
- 1
server/sonar-web/src/main/js/components/tutorials/manual/ProjectAnalysisStep.tsx Visa fil

@@ -51,7 +51,7 @@ export default class ProjectAnalysisStep extends React.PureComponent<Props, Stat
return (
<div className="boxed-group-inner">
<div className="display-flex-column">
<BuildToolForm component={this.props.component} onDone={this.handleBuildToolSelect} />
<BuildToolForm onDone={this.handleBuildToolSelect} />

{this.state.config && (
<div className="huge-spacer-top">

+ 1
- 4
server/sonar-web/src/main/js/components/tutorials/manual/__tests__/BuildToolForm-test.tsx Visa fil

@@ -19,7 +19,6 @@
*/
import { shallow } from 'enzyme';
import * as React from 'react';
import { mockComponent } from '../../../../helpers/testMocks';
import { BuildTools, OSs } from '../../types';
import BuildToolForm from '../BuildToolForm';

@@ -47,7 +46,5 @@ it('correctly calls the onDone prop', () => {
});

function shallowRender(props: Partial<BuildToolForm['props']> = {}) {
return shallow<BuildToolForm>(
<BuildToolForm component={mockComponent()} onDone={jest.fn()} {...props} />
);
return shallow<BuildToolForm>(<BuildToolForm onDone={jest.fn()} {...props} />);
}

+ 1
- 0
sonar-core/src/main/resources/org/sonar/l10n/core.properties Visa fil

@@ -3594,6 +3594,7 @@ branch_like_navigation.only_one_branch.title=Learn how to analyze branches in So
branch_like_navigation.only_one_branch.content=Quickly setup branch analysis and get separate insights for each of your branches and Pull Requests.
branch_like_navigation.only_one_branch.documentation=Branches documentation
branch_like_navigation.only_one_branch.pr_analysis=Pull Request analysis
branch_like_navigation.tutorial_for_ci=Show me how to set up my CI

#------------------------------------------------------------------------------
#

Laddar…
Avbryt
Spara