diff options
author | Jeremy Davis <jeremy.davis@sonarsource.com> | 2020-04-30 11:40:31 +0200 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2020-04-30 20:03:45 +0000 |
commit | 01a703dd8baa53f114195ba035aca1fabda90801 (patch) | |
tree | c4f17e974f5ea6e87e3104e88282281a2b8b1efb | |
parent | cf83220177ca46e9f5cb6cf56e0cb49ac5bd9c59 (diff) | |
download | sonarqube-01a703dd8baa53f114195ba035aca1fabda90801.tar.gz sonarqube-01a703dd8baa53f114195ba035aca1fabda90801.zip |
SONAR-13342 Fix broken projects links in portfolios
7 files changed, 221 insertions, 76 deletions
diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/TaskComponent.tsx b/server/sonar-web/src/main/js/apps/background-tasks/components/TaskComponent.tsx index bd9c27cb058..9a7b9662ebb 100644 --- a/server/sonar-web/src/main/js/apps/background-tasks/components/TaskComponent.tsx +++ b/server/sonar-web/src/main/js/apps/background-tasks/components/TaskComponent.tsx @@ -23,7 +23,13 @@ import BranchIcon from 'sonar-ui-common/components/icons/BranchIcon'; import PullRequestIcon from 'sonar-ui-common/components/icons/PullRequestIcon'; import QualifierIcon from 'sonar-ui-common/components/icons/QualifierIcon'; import Organization from '../../../components/shared/Organization'; -import { getBranchUrl, getProjectUrl, getPullRequestUrl } from '../../../helpers/urls'; +import { + getBranchUrl, + getPortfolioUrl, + getProjectUrl, + getPullRequestUrl +} from '../../../helpers/urls'; +import { ComponentQualifier } from '../../../types/component'; import TaskType from './TaskType'; interface Props { @@ -79,7 +85,9 @@ export default function TaskComponent({ task }: Props) { } function getTaskComponentUrl(componentKey: string, task: T.Task) { - if (task.branch) { + if (task.componentQualifier === ComponentQualifier.Portfolio) { + return getPortfolioUrl(componentKey); + } else if (task.branch) { return getBranchUrl(componentKey, task.branch); } else if (task.pullRequest) { return getPullRequestUrl(componentKey, task.pullRequest); diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/TaskComponent-test.tsx b/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/TaskComponent-test.tsx index 3b74956ba00..13477c7d4dc 100644 --- a/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/TaskComponent-test.tsx +++ b/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/TaskComponent-test.tsx @@ -19,27 +19,31 @@ */ import { shallow } from 'enzyme'; import * as React from 'react'; +import { ComponentQualifier } from '../../../../types/component'; import TaskComponent from '../TaskComponent'; -const TASK = { - componentKey: 'foo', - componentName: 'foo', - componentQualifier: 'TRK', - id: 'bar', - organization: 'org', - status: 'PENDING', - submittedAt: '2017-01-01', - submitterLogin: 'yoda', - type: 'REPORT' -}; - it('renders correctly', () => { - expect(shallow(<TaskComponent task={TASK} />)).toMatchSnapshot(); - expect(shallow(<TaskComponent task={{ ...TASK, componentKey: undefined }} />)).toMatchSnapshot(); + expect(shallowRender()).toMatchSnapshot(); + expect(shallowRender({ componentKey: undefined })).toMatchSnapshot('undefined key'); + expect(shallowRender({ componentQualifier: ComponentQualifier.Portfolio })).toMatchSnapshot( + 'portfolio' + ); + expect(shallowRender({ branch: 'feature' })).toMatchSnapshot('branch'); + expect(shallowRender({ branch: 'branch-6.7' })).toMatchSnapshot('branch'); + expect(shallowRender({ pullRequest: 'pr-89' })).toMatchSnapshot('pull request'); }); -it('renders correctly for branches and pullrequest', () => { - expect(shallow(<TaskComponent task={{ ...TASK, branch: 'feature' }} />)).toMatchSnapshot(); - expect(shallow(<TaskComponent task={{ ...TASK, branch: 'branch-6.7' }} />)).toMatchSnapshot(); - expect(shallow(<TaskComponent task={{ ...TASK, pullRequest: 'pr-89' }} />)).toMatchSnapshot(); -}); +function shallowRender(taskOverrides: Partial<T.Task> = {}) { + const TASK = { + componentKey: 'foo', + componentName: 'foo', + componentQualifier: 'TRK', + id: 'bar', + organization: 'org', + status: 'PENDING', + submittedAt: '2017-01-01', + submitterLogin: 'yoda', + type: 'REPORT' + }; + return shallow(<TaskComponent task={{ ...TASK, ...taskOverrides }} />); +} diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/TaskComponent-test.tsx.snap b/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/TaskComponent-test.tsx.snap index 653b69c156f..c6704006123 100644 --- a/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/TaskComponent-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/TaskComponent-test.tsx.snap @@ -34,20 +34,7 @@ exports[`renders correctly 1`] = ` </td> `; -exports[`renders correctly 2`] = ` -<td> - <span - className="note" - > - bar - </span> - <TaskType - type="REPORT" - /> -</td> -`; - -exports[`renders correctly for branches and pullrequest 1`] = ` +exports[`renders correctly: branch 1`] = ` <td> <BranchIcon className="little-spacer-right" @@ -93,7 +80,7 @@ exports[`renders correctly for branches and pullrequest 1`] = ` </td> `; -exports[`renders correctly for branches and pullrequest 2`] = ` +exports[`renders correctly: branch 2`] = ` <td> <BranchIcon className="little-spacer-right" @@ -139,7 +126,40 @@ exports[`renders correctly for branches and pullrequest 2`] = ` </td> `; -exports[`renders correctly for branches and pullrequest 3`] = ` +exports[`renders correctly: portfolio 1`] = ` +<td> + <span + className="little-spacer-right" + > + <QualifierIcon + qualifier="VW" + /> + </span> + <Connect(Organization) + organizationKey="org" + /> + <Link + className="spacer-right" + onlyActiveOnIndex={false} + style={Object {}} + to={ + Object { + "pathname": "/portfolio", + "query": Object { + "id": "foo", + }, + } + } + > + foo + </Link> + <TaskType + type="REPORT" + /> +</td> +`; + +exports[`renders correctly: pull request 1`] = ` <td> <PullRequestIcon className="little-spacer-right" @@ -183,3 +203,16 @@ exports[`renders correctly for branches and pullrequest 3`] = ` /> </td> `; + +exports[`renders correctly: undefined key 1`] = ` +<td> + <span + className="note" + > + bar + </span> + <TaskType + type="REPORT" + /> +</td> +`; diff --git a/server/sonar-web/src/main/js/apps/overview/components/App.tsx b/server/sonar-web/src/main/js/apps/overview/components/App.tsx index fbd6ea0c950..2fb35de7b06 100644 --- a/server/sonar-web/src/main/js/apps/overview/components/App.tsx +++ b/server/sonar-web/src/main/js/apps/overview/components/App.tsx @@ -39,17 +39,6 @@ interface Props { } export class App extends React.PureComponent<Props> { - componentDidMount() { - const { component } = this.props; - - if (this.isPortfolio()) { - this.props.router.replace({ - pathname: '/portfolio', - query: { id: component.key } - }); - } - } - isPortfolio = () => { return ([ComponentQualifier.Portfolio, ComponentQualifier.SubPortfolio] as string[]).includes( this.props.component.qualifier @@ -63,28 +52,24 @@ export class App extends React.PureComponent<Props> { return null; } - return ( + return isPullRequest(branchLike) ? ( <> - {isPullRequest(branchLike) ? ( - <> - <Suggestions suggestions="pull_requests" /> - <PullRequestOverview branchLike={branchLike} component={component} /> - </> - ) : ( - <> - <Suggestions suggestions="overview" /> + <Suggestions suggestions="pull_requests" /> + <PullRequestOverview branchLike={branchLike} component={component} /> + </> + ) : ( + <> + <Suggestions suggestions="overview" /> - {!component.analysisDate ? ( - <EmptyOverview - branchLike={branchLike} - branchLikes={branchLikes} - component={component} - hasAnalyses={this.props.isPending || this.props.isInProgress} - /> - ) : ( - <BranchOverview branchLike={branchLike} component={component} /> - )} - </> + {!component.analysisDate ? ( + <EmptyOverview + branchLike={branchLike} + branchLikes={branchLikes} + component={component} + hasAnalyses={this.props.isPending || this.props.isInProgress} + /> + ) : ( + <BranchOverview branchLike={branchLike} component={component} /> )} </> ); diff --git a/server/sonar-web/src/main/js/apps/projectsManagement/ProjectRow.tsx b/server/sonar-web/src/main/js/apps/projectsManagement/ProjectRow.tsx index dc32383e3e1..a12364c1a7f 100644 --- a/server/sonar-web/src/main/js/apps/projectsManagement/ProjectRow.tsx +++ b/server/sonar-web/src/main/js/apps/projectsManagement/ProjectRow.tsx @@ -25,6 +25,8 @@ import QualifierIcon from 'sonar-ui-common/components/icons/QualifierIcon'; import DateTooltipFormatter from 'sonar-ui-common/components/intl/DateTooltipFormatter'; import { Project } from '../../api/components'; import PrivacyBadgeContainer from '../../components/common/PrivacyBadgeContainer'; +import { getPortfolioUrl, getProjectUrl } from '../../helpers/urls'; +import { ComponentQualifier } from '../../types/component'; import './ProjectRow.css'; import ProjectRowActions from './ProjectRowActions'; @@ -41,6 +43,12 @@ export default class ProjectRow extends React.PureComponent<Props> { this.props.onProjectCheck(this.props.project, checked); }; + getComponentUrl(project: Project) { + return project.qualifier === ComponentQualifier.Portfolio + ? getPortfolioUrl(project.key) + : getProjectUrl(project.key); + } + render() { const { organization, project, selected } = this.props; @@ -51,10 +59,8 @@ export default class ProjectRow extends React.PureComponent<Props> { </td> <td className="nowrap hide-overflow project-row-text-cell"> - <Link - className="link-with-icon" - to={{ pathname: '/dashboard', query: { id: project.key } }}> - <QualifierIcon qualifier={project.qualifier} /> + <Link className="link-with-icon" to={this.getComponentUrl(project)}> + <QualifierIcon className="little-spacer-right" qualifier={project.qualifier} /> <Tooltip overlay={project.name} placement="left"> <span>{project.name}</span> diff --git a/server/sonar-web/src/main/js/apps/projectsManagement/__tests__/ProjectRow-test.tsx b/server/sonar-web/src/main/js/apps/projectsManagement/__tests__/ProjectRow-test.tsx index 60deca5f98d..b1117bd40a6 100644 --- a/server/sonar-web/src/main/js/apps/projectsManagement/__tests__/ProjectRow-test.tsx +++ b/server/sonar-web/src/main/js/apps/projectsManagement/__tests__/ProjectRow-test.tsx @@ -19,20 +19,24 @@ */ import { shallow } from 'enzyme'; import * as React from 'react'; +import { ComponentQualifier, Visibility } from '../../../types/component'; import ProjectRow from '../ProjectRow'; const project = { key: 'project', name: 'Project', - qualifier: 'TRK', - visibility: 'private' + qualifier: ComponentQualifier.Project, + visibility: Visibility.Private }; it('renders', () => { expect(shallowRender()).toMatchSnapshot(); expect( shallowRender({ project: { ...project, lastAnalysisDate: '2017-04-08T00:00:00.000Z' } }) - ).toMatchSnapshot(); + ).toMatchSnapshot('with lastAnalysisDate'); + expect( + shallowRender({ project: { ...project, qualifier: ComponentQualifier.Portfolio } }) + ).toMatchSnapshot('portfolio'); }); it('checks project', () => { diff --git a/server/sonar-web/src/main/js/apps/projectsManagement/__tests__/__snapshots__/ProjectRow-test.tsx.snap b/server/sonar-web/src/main/js/apps/projectsManagement/__tests__/__snapshots__/ProjectRow-test.tsx.snap index bae87bce87c..15c4f5964f2 100644 --- a/server/sonar-web/src/main/js/apps/projectsManagement/__tests__/__snapshots__/ProjectRow-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/projectsManagement/__tests__/__snapshots__/ProjectRow-test.tsx.snap @@ -24,12 +24,14 @@ exports[`renders 1`] = ` Object { "pathname": "/dashboard", "query": Object { + "branch": undefined, "id": "project", }, } } > <QualifierIcon + className="little-spacer-right" qualifier="TRK" /> <Tooltip @@ -100,7 +102,108 @@ exports[`renders 1`] = ` </tr> `; -exports[`renders 2`] = ` +exports[`renders: portfolio 1`] = ` +<tr + data-project-key="project" +> + <td + className="thin" + > + <Checkbox + checked={true} + onCheck={[Function]} + thirdState={false} + /> + </td> + <td + className="nowrap hide-overflow project-row-text-cell" + > + <Link + className="link-with-icon" + onlyActiveOnIndex={false} + style={Object {}} + to={ + Object { + "pathname": "/portfolio", + "query": Object { + "id": "project", + }, + } + } + > + <QualifierIcon + className="little-spacer-right" + qualifier="VW" + /> + <Tooltip + overlay="Project" + placement="left" + > + <span> + Project + </span> + </Tooltip> + </Link> + </td> + <td + className="thin nowrap" + > + <Connect(PrivacyBadge) + qualifier="VW" + tooltipProps={ + Object { + "projectKey": "project", + } + } + visibility="private" + /> + </td> + <td + className="nowrap hide-overflow project-row-text-cell" + > + <Tooltip + overlay="project" + placement="left" + > + <span + className="note" + > + project + </span> + </Tooltip> + </td> + <td + className="thin nowrap text-right" + > + <span + className="note" + > + — + </span> + </td> + <td + className="thin nowrap" + > + <ProjectRowActions + currentUser={ + Object { + "login": "foo", + } + } + project={ + Object { + "key": "project", + "name": "Project", + "qualifier": "VW", + "visibility": "private", + } + } + /> + </td> +</tr> +`; + +exports[`renders: with lastAnalysisDate 1`] = ` <tr data-project-key="project" > @@ -124,12 +227,14 @@ exports[`renders 2`] = ` Object { "pathname": "/dashboard", "query": Object { + "branch": undefined, "id": "project", }, } } > <QualifierIcon + className="little-spacer-right" qualifier="TRK" /> <Tooltip |