diff options
author | Stas Vilchik <stas.vilchik@sonarsource.com> | 2019-01-02 15:43:44 +0100 |
---|---|---|
committer | SonarTech <sonartech@sonarsource.com> | 2019-01-07 20:21:00 +0100 |
commit | a9d11467496a6a30955921a24e88d78f1b165a5b (patch) | |
tree | fb3a6119315bbfd92869e6b4cdbdbd534c992370 | |
parent | b8484b43efee19dc518b4451fe5879d40f33a3dd (diff) | |
download | sonarqube-a9d11467496a6a30955921a24e88d78f1b165a5b.tar.gz sonarqube-a9d11467496a6a30955921a24e88d78f1b165a5b.zip |
drop /component url
19 files changed, 158 insertions, 214 deletions
diff --git a/server/sonar-web/src/main/js/app/utils/startReactApp.tsx b/server/sonar-web/src/main/js/app/utils/startReactApp.tsx index 68ae6f8ccb5..781120376f3 100644 --- a/server/sonar-web/src/main/js/app/utils/startReactApp.tsx +++ b/server/sonar-web/src/main/js/app/utils/startReactApp.tsx @@ -34,7 +34,6 @@ import accountRoutes from '../../apps/account/routes'; import backgroundTasksRoutes from '../../apps/background-tasks/routes'; import codeRoutes from '../../apps/code/routes'; import codingRulesRoutes from '../../apps/coding-rules/routes'; -import componentRoutes from '../../apps/component/routes'; import componentMeasuresRoutes from '../../apps/component-measures/routes'; import customMeasuresRoutes from '../../apps/custom-measures/routes'; import groupsRoutes from '../../apps/groups/routes'; @@ -172,7 +171,6 @@ export default function startReactApp( {!isSonarCloud() && ( <RouteWithChildRoutes path="coding_rules" childRoutes={codingRulesRoutes} /> )} - <RouteWithChildRoutes path="component" childRoutes={componentRoutes} /> <RouteWithChildRoutes path="documentation" childRoutes={documentationRoutes} /> <Route path="explore" component={Explore}> <Route path="issues" component={ExploreIssues} /> diff --git a/server/sonar-web/src/main/js/apps/code/components/App.tsx b/server/sonar-web/src/main/js/apps/code/components/App.tsx index 02904305e0c..ca8f1d392fb 100644 --- a/server/sonar-web/src/main/js/apps/code/components/App.tsx +++ b/server/sonar-web/src/main/js/apps/code/components/App.tsx @@ -21,13 +21,14 @@ import * as React from 'react'; import * as classNames from 'classnames'; import { connect } from 'react-redux'; import Helmet from 'react-helmet'; +import { Location } from 'history'; import Components from './Components'; import Breadcrumbs from './Breadcrumbs'; import Search from './Search'; +import SourceViewerWrapper from './SourceViewerWrapper'; import { addComponent, addComponentBreadcrumbs, clearBucket } from '../bucket'; import { retrieveComponentChildren, retrieveComponent, loadMoreChildren } from '../utils'; import ListFooter from '../../../components/controls/ListFooter'; -import SourceViewer from '../../../components/SourceViewer/SourceViewer'; import Suggestions from '../../../app/components/embed-docs-modal/Suggestions'; import { fetchMetrics } from '../../../store/rootActions'; import { getMetrics } from '../../../store/rootReducer'; @@ -46,7 +47,7 @@ interface DispatchToProps { interface OwnProps { branchLike?: T.BranchLike; component: T.Component; - location: { query: { [x: string]: string } }; + location: Pick<Location, 'query'>; } type Props = StateToProps & DispatchToProps & OwnProps; @@ -175,7 +176,7 @@ export class App extends React.PureComponent<Props, State> { }; render() { - const { branchLike, component } = this.props; + const { branchLike, component, location } = this.props; const { loading, baseComponent, components, breadcrumbs, total, sourceViewer } = this.state; const shouldShowBreadcrumbs = breadcrumbs.length > 1; @@ -224,7 +225,11 @@ export class App extends React.PureComponent<Props, State> { {sourceViewer !== undefined && ( <div className="spacer-top"> - <SourceViewer branchLike={branchLike} component={sourceViewer.key} /> + <SourceViewerWrapper + branchLike={branchLike} + component={sourceViewer.key} + location={location} + /> </div> )} </div> diff --git a/server/sonar-web/src/main/js/apps/code/components/SourceViewerWrapper.tsx b/server/sonar-web/src/main/js/apps/code/components/SourceViewerWrapper.tsx new file mode 100644 index 00000000000..a3797f28d28 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/code/components/SourceViewerWrapper.tsx @@ -0,0 +1,54 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 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 { Location } from 'history'; +import SourceViewer from '../../../components/SourceViewer/SourceViewer'; +import { scrollToElement } from '../../../helpers/scrolling'; + +interface Props { + branchLike?: T.BranchLike; + component: string; + location: Pick<Location, 'query'>; +} + +export default function SourceViewerWrapper({ branchLike, component, location }: Props) { + const { line } = location.query; + + const scrollToLine = () => { + if (line) { + const row = document.querySelector(`.source-line[data-line-number="${line}"]`); + if (row) { + scrollToElement(row, { smooth: false, bottomOffset: window.innerHeight / 2 - 60 }); + } + } + }; + + const finalLine = line ? Number(line) : undefined; + + return ( + <SourceViewer + aroundLine={finalLine} + branchLike={branchLike} + component={component} + highlightedLine={finalLine} + onLoaded={scrollToLine} + /> + ); +} diff --git a/server/sonar-web/src/main/js/apps/component/components/App.tsx b/server/sonar-web/src/main/js/apps/component/components/App.tsx deleted file mode 100644 index bef13324450..00000000000 --- a/server/sonar-web/src/main/js/apps/component/components/App.tsx +++ /dev/null @@ -1,71 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 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 SourceViewer from '../../../components/SourceViewer/SourceViewer'; -import { fillBranchLike } from '../../../helpers/branches'; - -interface Props { - location: { - query: { - branch?: string; - id: string; - line?: string; - pullRequest?: string; - }; - }; -} - -export default class App extends React.PureComponent<Props> { - scrollToLine = () => { - const { line } = this.props.location.query; - if (line) { - const row = document.querySelector(`.source-line[data-line-number="${line}"]`); - if (row) { - const rect = row.getBoundingClientRect(); - const topOffset = window.innerHeight / 2 - 60; - const goal = rect.top - topOffset; - window.scrollTo(0, goal); - } - } - }; - - render() { - const { branch, id, line, pullRequest } = this.props.location.query; - - const finalLine = line ? Number(line) : undefined; - - // TODO find a way to avoid creating this fakeBranchLike - // probably the best way would be to drop this page completely - // and redirect to the Code page - const fakeBranchLike = fillBranchLike(branch, pullRequest); - - return ( - <div className="page page-limited"> - <SourceViewer - aroundLine={finalLine} - branchLike={fakeBranchLike} - component={id} - highlightedLine={finalLine} - onLoaded={this.scrollToLine} - /> - </div> - ); - } -} diff --git a/server/sonar-web/src/main/js/apps/component/components/__tests__/__snapshots__/App-test.tsx.snap b/server/sonar-web/src/main/js/apps/component/components/__tests__/__snapshots__/App-test.tsx.snap deleted file mode 100644 index 80a0c87199c..00000000000 --- a/server/sonar-web/src/main/js/apps/component/components/__tests__/__snapshots__/App-test.tsx.snap +++ /dev/null @@ -1,22 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`renders 1`] = ` -<div - className="page page-limited" -> - <LazyLoader - aroundLine={7} - branchLike={ - Object { - "isMain": false, - "mergeBranch": "", - "name": "b", - "type": "SHORT", - } - } - component="foo" - highlightedLine={7} - onLoaded={[Function]} - /> -</div> -`; diff --git a/server/sonar-web/src/main/js/apps/component/routes.ts b/server/sonar-web/src/main/js/apps/component/routes.ts deleted file mode 100644 index 094046e8466..00000000000 --- a/server/sonar-web/src/main/js/apps/component/routes.ts +++ /dev/null @@ -1,28 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 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 { lazyLoad } from '../../components/lazyLoad'; - -const routes = [ - { - indexRoute: { component: lazyLoad(() => import('./components/App')) } - } -]; - -export default routes; diff --git a/server/sonar-web/src/main/js/apps/issues/components/__tests__/__snapshots__/ComponentBreadcrumbs-test.tsx.snap b/server/sonar-web/src/main/js/apps/issues/components/__tests__/__snapshots__/ComponentBreadcrumbs-test.tsx.snap index c0182df2b97..dea3a478dcb 100644 --- a/server/sonar-web/src/main/js/apps/issues/components/__tests__/__snapshots__/ComponentBreadcrumbs-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/issues/components/__tests__/__snapshots__/ComponentBreadcrumbs-test.tsx.snap @@ -41,6 +41,7 @@ exports[`renders 1`] = ` "pathname": "/code", "query": Object { "id": "proj", + "line": undefined, "selected": "comp", }, } @@ -122,6 +123,7 @@ exports[`renders with branch 1`] = ` "query": Object { "branch": "feature", "id": "proj", + "line": undefined, "selected": "comp", }, } @@ -200,6 +202,7 @@ exports[`renders with sub-project 1`] = ` "pathname": "/code", "query": Object { "id": "proj", + "line": undefined, "selected": "comp", }, } diff --git a/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerBase.tsx b/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerBase.tsx index 8d914ec0bec..db24f1d0ceb 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerBase.tsx +++ b/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerBase.tsx @@ -22,6 +22,7 @@ import * as classNames from 'classnames'; import { intersection, uniqBy } from 'lodash'; import SourceViewerHeader from './SourceViewerHeader'; import SourceViewerCode from './SourceViewerCode'; +import { SourceViewerContext } from './SourceViewerContext'; import DuplicationPopup from './components/DuplicationPopup'; import defaultLoadIssues from './helpers/loadIssues'; import getCoverageStatus from './helpers/getCoverageStatus'; @@ -703,23 +704,25 @@ export default class SourceViewerBase extends React.PureComponent<Props, State> }); return ( - <div className={className} ref={node => (this.node = node)}> - <WorkspaceContext.Consumer> - {({ openComponent }) => ( - <SourceViewerHeader - branchLike={this.props.branchLike} - openComponent={openComponent} - sourceViewerFile={component} - /> + <SourceViewerContext.Provider value={{ branchLike: this.props.branchLike, file: component }}> + <div className={className} ref={node => (this.node = node)}> + <WorkspaceContext.Consumer> + {({ openComponent }) => ( + <SourceViewerHeader + branchLike={this.props.branchLike} + openComponent={openComponent} + sourceViewerFile={component} + /> + )} + </WorkspaceContext.Consumer> + {sourceRemoved && ( + <Alert className="spacer-top" variant="warning"> + {translate('code_viewer.no_source_code_displayed_due_to_source_removed')} + </Alert> )} - </WorkspaceContext.Consumer> - {sourceRemoved && ( - <Alert className="spacer-top" variant="warning"> - {translate('code_viewer.no_source_code_displayed_due_to_source_removed')} - </Alert> - )} - {!sourceRemoved && sources !== undefined && this.renderCode(sources)} - </div> + {!sourceRemoved && sources !== undefined && this.renderCode(sources)} + </div> + </SourceViewerContext.Provider> ); } } diff --git a/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerCode.tsx b/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerCode.tsx index 4b0c419e2ba..923f3b6ff9f 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerCode.tsx +++ b/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerCode.tsx @@ -156,7 +156,6 @@ export default class SourceViewerCode extends React.PureComponent<Props> { return ( <Line branchLike={this.props.branchLike} - componentKey={this.props.componentKey} displayAllIssues={this.props.displayAllIssues} displayCoverage={displayCoverage} displayDuplications={displayDuplications} diff --git a/server/sonar-web/src/main/js/apps/component/components/__tests__/App-test.tsx b/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerContext.tsx index 935c1680a6a..a546d03802f 100644 --- a/server/sonar-web/src/main/js/apps/component/components/__tests__/App-test.tsx +++ b/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerContext.tsx @@ -18,11 +18,13 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import * as React from 'react'; -import { shallow } from 'enzyme'; -import App from '../App'; -it('renders', () => { - expect( - shallow(<App location={{ query: { branch: 'b', id: 'foo', line: '7' } }} />) - ).toMatchSnapshot(); -}); +interface SourceViewerContextShape { + branchLike?: T.BranchLike; + file: T.SourceViewerFile; +} + +export const SourceViewerContext = React.createContext({ + branchLike: {}, + file: {} +}) as React.Context<SourceViewerContextShape>; diff --git a/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerHeader.tsx b/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerHeader.tsx index 53e896eff12..bd11c8c615d 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerHeader.tsx +++ b/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerHeader.tsx @@ -32,7 +32,8 @@ import { getPathUrlAsString, getBranchLikeUrl, getComponentIssuesUrl, - getBaseUrl + getBaseUrl, + getCodeUrl } from '../../helpers/urls'; import { collapsedDirFromPath, fileFromPath } from '../../helpers/path'; import { translate } from '../../helpers/l10n'; @@ -136,15 +137,13 @@ export default class SourceViewerHeader extends React.PureComponent<Props, State </a> </li> <li> - <a + <Link className="js-new-window" - href={getPathUrlAsString({ - pathname: '/component', - query: { id: key, ...getBranchLikeQuery(this.props.branchLike) } - })} - target="_blank"> + rel="noopener noreferrer" + target="_blank" + to={getCodeUrl(this.props.sourceViewerFile.project, this.props.branchLike, key)}> {translate('component_viewer.new_window')} - </a> + </Link> </li> {!workspace && ( <li> @@ -154,7 +153,11 @@ export default class SourceViewerHeader extends React.PureComponent<Props, State </li> )} <li> - <a className="js-raw-source" href={rawSourcesLink} target="_blank"> + <a + className="js-raw-source" + href={rawSourcesLink} + rel="noopener noreferrer" + target="_blank"> {translate('component_viewer.show_raw_source')} </a> </li> diff --git a/server/sonar-web/src/main/js/components/SourceViewer/components/Line.tsx b/server/sonar-web/src/main/js/components/SourceViewer/components/Line.tsx index e7f315caec5..7955f4df686 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/components/Line.tsx +++ b/server/sonar-web/src/main/js/components/SourceViewer/components/Line.tsx @@ -30,7 +30,6 @@ import LineCode from './LineCode'; interface Props { branchLike: T.BranchLike | undefined; - componentKey: string; displayAllIssues?: boolean; displayCoverage: boolean; displayDuplications: boolean; @@ -112,8 +111,6 @@ export default class Line extends React.PureComponent<Props> { return ( <tr className={className} data-line-number={line.line}> <LineNumber - branchLike={this.props.branchLike} - componentKey={this.props.componentKey} line={line} onPopupToggle={this.props.onLinePopupToggle} popupOpen={this.isPopupOpen('line-number')} diff --git a/server/sonar-web/src/main/js/components/SourceViewer/components/LineNumber.tsx b/server/sonar-web/src/main/js/components/SourceViewer/components/LineNumber.tsx index c190e5a004c..5d90fb7acdd 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/components/LineNumber.tsx +++ b/server/sonar-web/src/main/js/components/SourceViewer/components/LineNumber.tsx @@ -22,8 +22,6 @@ import LineOptionsPopup from './LineOptionsPopup'; import Toggler from '../../controls/Toggler'; interface Props { - branchLike: T.BranchLike | undefined; - componentKey: string; line: T.SourceLine; onPopupToggle: (x: { index?: number; line: number; name: string; open?: boolean }) => void; popupOpen: boolean; @@ -46,7 +44,7 @@ export default class LineNumber extends React.PureComponent<Props> { }; render() { - const { branchLike, componentKey, line, popupOpen } = this.props; + const { line, popupOpen } = this.props; const { line: lineNumber } = line; const hasLineNumber = !!lineNumber; return hasLineNumber ? ( @@ -60,9 +58,7 @@ export default class LineNumber extends React.PureComponent<Props> { <Toggler onRequestClose={this.closePopup} open={popupOpen} - overlay={ - <LineOptionsPopup branchLike={branchLike} componentKey={componentKey} line={line} /> - } + overlay={<LineOptionsPopup line={line} />} /> </td> ) : ( diff --git a/server/sonar-web/src/main/js/components/SourceViewer/components/LineOptionsPopup.tsx b/server/sonar-web/src/main/js/components/SourceViewer/components/LineOptionsPopup.tsx index 24875c9404d..5beb76d4c8c 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/components/LineOptionsPopup.tsx +++ b/server/sonar-web/src/main/js/components/SourceViewer/components/LineOptionsPopup.tsx @@ -22,26 +22,32 @@ import { Link } from 'react-router'; import { DropdownOverlay } from '../../controls/Dropdown'; import { PopupPlacement } from '../../ui/popups'; import { translate } from '../../../helpers/l10n'; -import { getBranchLikeQuery } from '../../../helpers/branches'; +import { getCodeUrl } from '../../../helpers/urls'; +import { SourceViewerContext } from '../SourceViewerContext'; interface Props { - branchLike: T.BranchLike | undefined; - componentKey: string; line: T.SourceLine; } -export default function LineOptionsPopup({ branchLike, componentKey, line }: Props) { - const permalink = { - pathname: '/component', - query: { id: componentKey, line: line.line, ...getBranchLikeQuery(branchLike) } - }; +export default function LineOptionsPopup({ line }: Props) { return ( - <DropdownOverlay placement={PopupPlacement.RightTop}> - <div className="source-viewer-bubble-popup nowrap"> - <Link className="js-get-permalink" to={permalink}> - {translate('component_viewer.get_permalink')} - </Link> - </div> - </DropdownOverlay> + <SourceViewerContext.Consumer> + {({ branchLike, file }) => ( + <DropdownOverlay placement={PopupPlacement.RightTop}> + <div className="source-viewer-bubble-popup nowrap"> + <Link + className="js-get-permalink" + onClick={event => { + event.stopPropagation(); + }} + rel="noopener noreferrer" + target="_blank" + to={getCodeUrl(file.project, branchLike, file.key, line.line)}> + {translate('component_viewer.get_permalink')} + </Link> + </div> + </DropdownOverlay> + )} + </SourceViewerContext.Consumer> ); } diff --git a/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/LineNumber-test.tsx b/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/LineNumber-test.tsx index 03cdce961f5..2b4a7453a9f 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/LineNumber-test.tsx +++ b/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/LineNumber-test.tsx @@ -24,29 +24,13 @@ import LineNumber from '../LineNumber'; it('render line 3', () => { const line = { line: 3 }; - const wrapper = shallow( - <LineNumber - branchLike={undefined} - componentKey="foo" - line={line} - onPopupToggle={jest.fn()} - popupOpen={false} - /> - ); + const wrapper = shallow(<LineNumber line={line} onPopupToggle={jest.fn()} popupOpen={false} />); expect(wrapper).toMatchSnapshot(); click(wrapper); }); it('render line 0', () => { const line = { line: 0 }; - const wrapper = shallow( - <LineNumber - branchLike={undefined} - componentKey="foo" - line={line} - onPopupToggle={jest.fn()} - popupOpen={false} - /> - ); + const wrapper = shallow(<LineNumber line={line} onPopupToggle={jest.fn()} popupOpen={false} />); expect(wrapper).toMatchSnapshot(); }); diff --git a/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/LineOptionsPopup-test.tsx b/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/LineOptionsPopup-test.tsx index a3fce5c3135..4bdb873af4f 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/LineOptionsPopup-test.tsx +++ b/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/LineOptionsPopup-test.tsx @@ -21,14 +21,18 @@ import * as React from 'react'; import { shallow } from 'enzyme'; import LineOptionsPopup from '../LineOptionsPopup'; +jest.mock('../../SourceViewerContext', () => ({ + SourceViewerContext: { + Consumer: (props: any) => + props.children({ + branchLike: { isMain: false, name: 'feature', type: 'SHORT' }, + file: { project: 'prj', key: 'foo' } + }) + } +})); + it('should render', () => { const line = { line: 3 }; - const branch: T.ShortLivingBranch = { - isMain: false, - mergeBranch: 'master', - name: 'feature', - type: 'SHORT' - }; - const wrapper = shallow(<LineOptionsPopup branchLike={branch} componentKey="foo" line={line} />); + const wrapper = shallow(<LineOptionsPopup line={line} />).dive(); expect(wrapper).toMatchSnapshot(); }); diff --git a/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/__snapshots__/LineNumber-test.tsx.snap b/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/__snapshots__/LineNumber-test.tsx.snap index 985f1f51937..a6bb1627d08 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/__snapshots__/LineNumber-test.tsx.snap +++ b/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/__snapshots__/LineNumber-test.tsx.snap @@ -19,7 +19,6 @@ exports[`render line 3 1`] = ` open={false} overlay={ <LineOptionsPopup - componentKey="foo" line={ Object { "line": 3, diff --git a/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/__snapshots__/LineOptionsPopup-test.tsx.snap b/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/__snapshots__/LineOptionsPopup-test.tsx.snap index 96b360bb80a..936909da9dc 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/__snapshots__/LineOptionsPopup-test.tsx.snap +++ b/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/__snapshots__/LineOptionsPopup-test.tsx.snap @@ -9,15 +9,19 @@ exports[`should render 1`] = ` > <Link className="js-get-permalink" + onClick={[Function]} onlyActiveOnIndex={false} + rel="noopener noreferrer" style={Object {}} + target="_blank" to={ Object { - "pathname": "/component", + "pathname": "/code", "query": Object { "branch": "feature", - "id": "foo", + "id": "prj", "line": 3, + "selected": "foo", }, } } diff --git a/server/sonar-web/src/main/js/helpers/urls.ts b/server/sonar-web/src/main/js/helpers/urls.ts index f899255e255..c7090bc6770 100644 --- a/server/sonar-web/src/main/js/helpers/urls.ts +++ b/server/sonar-web/src/main/js/helpers/urls.ts @@ -219,8 +219,16 @@ export function getMarkdownHelpUrl(): string { return getBaseUrl() + '/markdown/help'; } -export function getCodeUrl(project: string, branchLike?: T.BranchLike, selected?: string) { - return { pathname: '/code', query: { id: project, ...getBranchLikeQuery(branchLike), selected } }; +export function getCodeUrl( + project: string, + branchLike?: T.BranchLike, + selected?: string, + line?: number +) { + return { + pathname: '/code', + query: { id: project, ...getBranchLikeQuery(branchLike), selected, line } + }; } export function getOrganizationUrl(organization: string) { |