@@ -25,6 +25,7 @@ import { addGlobalErrorMessage } from '../../../store/globalMessages/duck'; | |||
import { getCurrentUser } from '../../../store/rootReducer'; | |||
import { translate } from '../../../helpers/l10n'; | |||
import { getExtensionStart } from './utils'; | |||
import getStore from '../../utils/getStore'; | |||
type Props = { | |||
currentUser: Object, | |||
@@ -58,7 +59,9 @@ class Extension extends React.Component { | |||
} | |||
handleStart = (start: Function) => { | |||
const store = getStore(); | |||
this.stop = start({ | |||
store, | |||
el: this.container, | |||
currentUser: this.props.currentUser, | |||
router: this.props.router, |
@@ -0,0 +1,32 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2017 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. | |||
*/ | |||
// @flow | |||
import React from 'react'; | |||
import GlobalPageExtension from './GlobalPageExtension'; | |||
export default class PortfoliosPage extends React.Component { | |||
render () { | |||
return ( | |||
<GlobalPageExtension | |||
location={this.props.location} | |||
params={{ pluginKey: 'governance', extensionKey: 'portfolios' }}/> | |||
); | |||
} | |||
} |
@@ -47,6 +47,16 @@ export default class GlobalNavMenu extends React.Component { | |||
); | |||
} | |||
renderPortfolios() { | |||
return ( | |||
<li> | |||
<Link to="/portfolios" activeClassName="active"> | |||
{translate('portfolios.page')} | |||
</Link> | |||
</li> | |||
); | |||
} | |||
renderIssuesLink() { | |||
const query = this.props.currentUser.isLoggedIn | |||
? '#resolved=false|assigned_to_me=true' | |||
@@ -114,7 +124,8 @@ export default class GlobalNavMenu extends React.Component { | |||
renderMore() { | |||
const { globalPages } = this.props.appState; | |||
if (globalPages.length === 0) { | |||
const withoutPortfolios = globalPages.filter(page => page.key !== 'governance/portfolios'); | |||
if (withoutPortfolios.length === 0) { | |||
return null; | |||
} | |||
return ( | |||
@@ -124,16 +135,19 @@ export default class GlobalNavMenu extends React.Component { | |||
<span className="icon-dropdown" /> | |||
</a> | |||
<ul className="dropdown-menu"> | |||
{globalPages.map(this.renderGlobalPageLink)} | |||
{withoutPortfolios.map(this.renderGlobalPageLink)} | |||
</ul> | |||
</li> | |||
); | |||
} | |||
render() { | |||
const governanceInstalled = this.props.appState.qualifiers.includes('VW'); | |||
return ( | |||
<ul className="nav navbar-nav"> | |||
{this.renderProjects()} | |||
{governanceInstalled && this.renderPortfolios()} | |||
{this.renderIssuesLink()} | |||
{this.renderRulesLink()} | |||
{this.renderProfilesLink()} |
@@ -23,7 +23,8 @@ import GlobalNavMenu from '../GlobalNavMenu'; | |||
it('should work with extensions', () => { | |||
const appState = { | |||
globalPages: [{ key: 'foo', name: 'Foo' }] | |||
globalPages: [{ key: 'foo', name: 'Foo' }], | |||
qualifiers: ['TRK'] | |||
}; | |||
const currentUser = { | |||
isLoggedIn: false, |
@@ -18,13 +18,21 @@ | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import moment from 'moment'; | |||
import * as ReactRedux from 'react-redux'; | |||
import * as measures from '../../helpers/measures'; | |||
import * as request from '../../helpers/request'; | |||
import FavoriteContainer from '../../components/controls/FavoriteContainer'; | |||
import ListFooter from '../../components/controls/ListFooter'; | |||
const exposeLibraries = () => { | |||
window.moment = moment; | |||
window.ReactRedux = ReactRedux; | |||
window.SonarMeasures = measures; | |||
window.SonarRequest = request; | |||
window.SonarComponents = { | |||
FavoriteContainer, | |||
ListFooter | |||
}; | |||
}; | |||
export default exposeLibraries; |
@@ -32,6 +32,7 @@ import ProjectAdminContainer from '../components/ProjectAdminContainer'; | |||
import ProjectPageExtension from '../components/extensions/ProjectPageExtension'; | |||
import ProjectAdminPageExtension from '../components/extensions/ProjectAdminPageExtension'; | |||
import ViewDashboard from '../components/extensions/ViewDashboard'; | |||
import PortfoliosPage from '../components/extensions/PortfoliosPage'; | |||
import AdminContainer from '../components/AdminContainer'; | |||
import GlobalPageExtension from '../components/extensions/GlobalPageExtension'; | |||
import GlobalAdminPageExtension from '../components/extensions/GlobalAdminPageExtension'; | |||
@@ -93,6 +94,8 @@ const startReactApp = () => { | |||
}} | |||
/> | |||
<Redirect from="/extension/governance/portfolios" to="/portfolios" /> | |||
<Route path="markdown/help" component={MarkdownHelp} /> | |||
<Route component={LocalizationContainer}> | |||
@@ -126,6 +129,7 @@ const startReactApp = () => { | |||
<Route path="organizations">{organizationsRouters}</Route> | |||
<Route path="projects">{projectsRoutes}</Route> | |||
<Route path="quality_gates">{qualityGatesRoutes}</Route> | |||
<Route path="portfolios" component={PortfoliosPage} /> | |||
<Route path="profiles">{qualityProfilesRoutes}</Route> | |||
<Route path="web_api">{webAPIRoutes}</Route> | |||
@@ -560,6 +560,7 @@ source.page=Source | |||
timemachine.page=Time Machine | |||
comparison.page=Compare | |||
view_projects.page=Projects | |||
portfolios.page=Portfolios | |||
project_activity.page=Activity | |||
project_activity.page.description=The page shows the history of project analyses. | |||