/* | |||||
* 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 { Alert } from '../../components/ui/Alert'; | |||||
import { translate } from '../../helpers/l10n'; | |||||
import { BranchLike } from '../../types/branch-like'; | |||||
import { isApplication } from '../../types/component'; | |||||
export interface NonAdminPagesContainerProps { | |||||
children: JSX.Element; | |||||
branchLike?: BranchLike; | |||||
branchLikes: BranchLike[]; | |||||
component: T.Component; | |||||
isInProgress?: boolean; | |||||
isPending?: boolean; | |||||
onBranchesChange: () => void; | |||||
onComponentChange: (changes: {}) => void; | |||||
} | |||||
export default function NonAdminPagesContainer(props: NonAdminPagesContainerProps) { | |||||
const { children, component } = props; | |||||
/* | |||||
* Catch Applications for which the user does not have access to all child projects | |||||
* and prevent displaying whatever page was requested. | |||||
* This doesn't apply to admin pages (those are not within this container) | |||||
*/ | |||||
if (isApplication(component.qualifier) && !component.canBrowseAllChildProjects) { | |||||
return ( | |||||
<div className="page page-limited display-flex-justify-center"> | |||||
<Alert className="max-width-60 huge-spacer-top" display="block" variant="error"> | |||||
<p>{translate('application.cannot_access_all_child_projects1')}</p> | |||||
<br /> | |||||
<p>{translate('application.cannot_access_all_child_projects2')}</p> | |||||
</Alert> | |||||
</div> | |||||
); | |||||
} | |||||
return React.cloneElement(children, props); | |||||
} |
/* | |||||
* 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 { mockComponent } from '../../../helpers/mocks/component'; | |||||
import { ComponentQualifier } from '../../../types/component'; | |||||
import NonAdminPagesContainer, { NonAdminPagesContainerProps } from '../NonAdminPagesContainer'; | |||||
function Child() { | |||||
return <div />; | |||||
} | |||||
it('should render correctly', () => { | |||||
expect( | |||||
shallowRender() | |||||
.find(Child) | |||||
.exists() | |||||
).toBe(true); | |||||
expect( | |||||
shallowRender({ | |||||
component: mockComponent({ | |||||
qualifier: ComponentQualifier.Application, | |||||
canBrowseAllChildProjects: true | |||||
}) | |||||
}) | |||||
.find(Child) | |||||
.exists() | |||||
).toBe(true); | |||||
const wrapper = shallowRender({ | |||||
component: mockComponent({ | |||||
qualifier: ComponentQualifier.Application | |||||
}) | |||||
}); | |||||
expect(wrapper.find(Child).exists()).toBe(false); | |||||
expect(wrapper).toMatchSnapshot(); | |||||
}); | |||||
function shallowRender(props: Partial<NonAdminPagesContainerProps> = {}) { | |||||
return shallow<NonAdminPagesContainerProps>( | |||||
<NonAdminPagesContainer | |||||
branchLikes={[]} | |||||
component={mockComponent()} | |||||
onBranchesChange={jest.fn()} | |||||
onComponentChange={jest.fn()} | |||||
{...props}> | |||||
<Child /> | |||||
</NonAdminPagesContainer> | |||||
); | |||||
} |
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||||
exports[`should render correctly 1`] = ` | |||||
<div | |||||
className="page page-limited display-flex-justify-center" | |||||
> | |||||
<Alert | |||||
className="max-width-60 huge-spacer-top" | |||||
display="block" | |||||
variant="error" | |||||
> | |||||
<p> | |||||
application.cannot_access_all_child_projects1 | |||||
</p> | |||||
<br /> | |||||
<p> | |||||
application.cannot_access_all_child_projects2 | |||||
</p> | |||||
</Alert> | |||||
</div> | |||||
`; |
import GlobalContainer from '../components/GlobalContainer'; | import GlobalContainer from '../components/GlobalContainer'; | ||||
import { PageContext } from '../components/indexation/PageUnavailableDueToIndexation'; | import { PageContext } from '../components/indexation/PageUnavailableDueToIndexation'; | ||||
import MigrationContainer from '../components/MigrationContainer'; | import MigrationContainer from '../components/MigrationContainer'; | ||||
import NonAdminPagesContainer from '../components/NonAdminPagesContainer'; | |||||
import getStore from './getStore'; | import getStore from './getStore'; | ||||
/* | /* | ||||
function renderComponentRoutes() { | function renderComponentRoutes() { | ||||
return ( | return ( | ||||
<Route component={lazyLoadComponent(() => import('../components/ComponentContainer'))}> | <Route component={lazyLoadComponent(() => import('../components/ComponentContainer'))}> | ||||
<RouteWithChildRoutes path="code" childRoutes={codeRoutes} /> | |||||
<RouteWithChildRoutes path="component_measures" childRoutes={componentMeasuresRoutes} /> | |||||
<RouteWithChildRoutes path="dashboard" childRoutes={overviewRoutes} /> | |||||
<RouteWithChildRoutes path="portfolio" childRoutes={portfolioRoutes} /> | |||||
<RouteWithChildRoutes path="project/activity" childRoutes={projectActivityRoutes} /> | |||||
<Route | |||||
path="project/extension/:pluginKey/:extensionKey" | |||||
component={lazyLoadComponent(() => import('../components/extensions/ProjectPageExtension'))} | |||||
/> | |||||
<Route | |||||
path="project/issues" | |||||
component={Issues} | |||||
onEnter={({ location: { query } }, replace) => { | |||||
if (query.types) { | |||||
if (query.types === 'SECURITY_HOTSPOT') { | |||||
replace({ | |||||
pathname: '/security_hotspots', | |||||
query: { ...pick(query, ['id', 'branch', 'pullRequest']), assignedToMe: false } | |||||
}); | |||||
} else { | |||||
query.types = query.types | |||||
.split(',') | |||||
.filter((type: string) => type !== 'SECURITY_HOTSPOT') | |||||
.join(','); | |||||
{/* This container is a catch-all for all non-admin pages */} | |||||
<Route component={NonAdminPagesContainer}> | |||||
<RouteWithChildRoutes path="code" childRoutes={codeRoutes} /> | |||||
<RouteWithChildRoutes path="component_measures" childRoutes={componentMeasuresRoutes} /> | |||||
<RouteWithChildRoutes path="dashboard" childRoutes={overviewRoutes} /> | |||||
<RouteWithChildRoutes path="portfolio" childRoutes={portfolioRoutes} /> | |||||
<RouteWithChildRoutes path="project/activity" childRoutes={projectActivityRoutes} /> | |||||
<Route | |||||
path="project/extension/:pluginKey/:extensionKey" | |||||
component={lazyLoadComponent(() => | |||||
import('../components/extensions/ProjectPageExtension') | |||||
)} | |||||
/> | |||||
<Route | |||||
path="project/issues" | |||||
component={Issues} | |||||
onEnter={({ location: { query } }, replace) => { | |||||
if (query.types) { | |||||
if (query.types === 'SECURITY_HOTSPOT') { | |||||
replace({ | |||||
pathname: '/security_hotspots', | |||||
query: { ...pick(query, ['id', 'branch', 'pullRequest']), assignedToMe: false } | |||||
}); | |||||
} else { | |||||
query.types = query.types | |||||
.split(',') | |||||
.filter((type: string) => type !== 'SECURITY_HOTSPOT') | |||||
.join(','); | |||||
} | |||||
} | } | ||||
} | |||||
}} | |||||
/> | |||||
<Route | |||||
path="security_hotspots" | |||||
component={lazyLoadComponent(() => | |||||
import('../../apps/security-hotspots/SecurityHotspotsApp') | |||||
)} | |||||
/> | |||||
<RouteWithChildRoutes path="project/quality_gate" childRoutes={projectQualityGateRoutes} /> | |||||
<RouteWithChildRoutes | |||||
path="project/quality_profiles" | |||||
childRoutes={projectQualityProfilesRoutes} | |||||
/> | |||||
<RouteWithChildRoutes path="tutorials" childRoutes={tutorialsRoutes} /> | |||||
}} | |||||
/> | |||||
<Route | |||||
path="security_hotspots" | |||||
component={lazyLoadComponent(() => | |||||
import('../../apps/security-hotspots/SecurityHotspotsApp') | |||||
)} | |||||
/> | |||||
<RouteWithChildRoutes path="project/quality_gate" childRoutes={projectQualityGateRoutes} /> | |||||
<RouteWithChildRoutes | |||||
path="project/quality_profiles" | |||||
childRoutes={projectQualityProfilesRoutes} | |||||
/> | |||||
<RouteWithChildRoutes path="tutorials" childRoutes={tutorialsRoutes} /> | |||||
</Route> | |||||
<Route component={lazyLoadComponent(() => import('../components/ProjectAdminContainer'))}> | <Route component={lazyLoadComponent(() => import('../components/ProjectAdminContainer'))}> | ||||
<Route | <Route | ||||
path="project/admin/extension/:pluginKey/:extensionKey" | path="project/admin/extension/:pluginKey/:extensionKey" |
branch_like_navigation.only_one_branch.pr_analysis=Pull Request analysis | 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 | branch_like_navigation.tutorial_for_ci=Show me how to set up my CI | ||||
#------------------------------------------------------------------------------ | |||||
# | |||||
# APPLICATIONS | |||||
# | |||||
#------------------------------------------------------------------------------ | |||||
application.cannot_access_all_child_projects1=You must have access to all the projects within this Application in order to browse it. | |||||
application.cannot_access_all_child_projects2=Please contact your project administrator. | |||||
#------------------------------------------------------------------------------ | #------------------------------------------------------------------------------ | ||||
# | # | ||||
# PORTFOLIOS | # PORTFOLIOS |