aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/src/main/js/apps
diff options
context:
space:
mode:
authorStas Vilchik <stas.vilchik@sonarsource.com>2017-08-17 21:39:59 +0200
committerJanos Gyerik <janos.gyerik@sonarsource.com>2017-09-12 11:34:36 +0200
commitcff416d7f9910c258bc8d7175c08afff96a9eb2a (patch)
tree78500908a2afde31b28ef938d4d61609d448f279 /server/sonar-web/src/main/js/apps
parent139467cf51932ba232190f363ad864e60eb3fd4d (diff)
downloadsonarqube-cff416d7f9910c258bc8d7175c08afff96a9eb2a.tar.gz
sonarqube-cff416d7f9910c258bc8d7175c08afff96a9eb2a.zip
SONAR-9702 Build UI for short-lived branches (#2371)
Diffstat (limited to 'server/sonar-web/src/main/js/apps')
-rw-r--r--server/sonar-web/src/main/js/apps/background-tasks/components/BackgroundTasksApp.js9
-rw-r--r--server/sonar-web/src/main/js/apps/background-tasks/components/TaskStatus.js2
-rw-r--r--server/sonar-web/src/main/js/apps/code/components/App.js36
-rw-r--r--server/sonar-web/src/main/js/apps/code/components/Component.js4
-rw-r--r--server/sonar-web/src/main/js/apps/code/components/ComponentDetach.js4
-rw-r--r--server/sonar-web/src/main/js/apps/code/components/ComponentName.js2
-rw-r--r--server/sonar-web/src/main/js/apps/code/components/ComponentPin.js4
-rw-r--r--server/sonar-web/src/main/js/apps/code/components/Search.js14
-rw-r--r--server/sonar-web/src/main/js/apps/code/routes.ts2
-rw-r--r--server/sonar-web/src/main/js/apps/code/utils.js24
-rw-r--r--server/sonar-web/src/main/js/apps/component-measures/components/AppContainer.js10
-rw-r--r--server/sonar-web/src/main/js/apps/custom-measures/components/CustomMeasuresAppContainer.js10
-rw-r--r--server/sonar-web/src/main/js/apps/custom-measures/routes.ts2
-rw-r--r--server/sonar-web/src/main/js/apps/issues/components/App.js15
-rw-r--r--server/sonar-web/src/main/js/apps/issues/components/AppContainer.js7
-rw-r--r--server/sonar-web/src/main/js/apps/issues/components/IssuesSourceViewer.js4
-rw-r--r--server/sonar-web/src/main/js/apps/issues/sidebar/CreationDateFacet.js4
-rw-r--r--server/sonar-web/src/main/js/apps/overview/components/App.js11
-rw-r--r--server/sonar-web/src/main/js/apps/overview/components/AppContainer.js28
-rw-r--r--server/sonar-web/src/main/js/apps/overview/components/OverviewApp.js10
-rw-r--r--server/sonar-web/src/main/js/apps/overview/meta/Meta.js11
-rw-r--r--server/sonar-web/src/main/js/apps/overview/meta/MetaTags.js16
-rw-r--r--server/sonar-web/src/main/js/apps/overview/meta/MetaTagsSelector.js (renamed from server/sonar-web/src/main/js/apps/projects/components/ProjectTagsSelectorContainer.js)12
-rw-r--r--server/sonar-web/src/main/js/apps/overview/meta/__tests__/MetaTagsSelector-test.js61
-rw-r--r--server/sonar-web/src/main/js/apps/overview/meta/__tests__/__snapshots__/MetaTags-test.js.snap3
-rw-r--r--server/sonar-web/src/main/js/apps/overview/routes.ts2
-rw-r--r--server/sonar-web/src/main/js/apps/project-admin/deletion/Deletion.js35
-rw-r--r--server/sonar-web/src/main/js/apps/project-admin/key/Key.js5
-rw-r--r--server/sonar-web/src/main/js/apps/project-admin/links/Links.js5
-rw-r--r--server/sonar-web/src/main/js/apps/project-admin/quality-gate/QualityGate.js9
-rw-r--r--server/sonar-web/src/main/js/apps/project-admin/quality-profiles/QualityProfiles.js4
-rw-r--r--server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityAppContainer.js32
-rw-r--r--server/sonar-web/src/main/js/apps/projectActivity/routes.ts2
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/AppContainer.js7
34 files changed, 206 insertions, 200 deletions
diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/BackgroundTasksApp.js b/server/sonar-web/src/main/js/apps/background-tasks/components/BackgroundTasksApp.js
index 9fa9496d367..8128a3827e3 100644
--- a/server/sonar-web/src/main/js/apps/background-tasks/components/BackgroundTasksApp.js
+++ b/server/sonar-web/src/main/js/apps/background-tasks/components/BackgroundTasksApp.js
@@ -38,7 +38,6 @@ import {
} from '../../../api/ce';
import { updateTask, mapFiltersToParameters } from '../utils';
/*:: import type { Task } from '../types'; */
-import { getComponent } from '../../../store/rootReducer';
import '../background-tasks.css';
import { fetchOrganizations } from '../../../store/rootActions';
import { translate } from '../../../helpers/l10n';
@@ -257,12 +256,6 @@ class BackgroundTasksApp extends React.PureComponent {
}
}
-const mapStateToProps = (state, ownProps) => ({
- component: ownProps.location.query.id
- ? getComponent(state, ownProps.location.query.id)
- : undefined
-});
-
const mapDispatchToProps = { fetchOrganizations };
-export default connect(mapStateToProps, mapDispatchToProps)(BackgroundTasksApp);
+export default connect(null, mapDispatchToProps)(BackgroundTasksApp);
diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/TaskStatus.js b/server/sonar-web/src/main/js/apps/background-tasks/components/TaskStatus.js
index 5a19455b17b..b2ef518c558 100644
--- a/server/sonar-web/src/main/js/apps/background-tasks/components/TaskStatus.js
+++ b/server/sonar-web/src/main/js/apps/background-tasks/components/TaskStatus.js
@@ -20,7 +20,7 @@
/* @flow */
import React from 'react';
import { STATUSES } from './../constants';
-import PendingIcon from '../../../components/shared/pending-icon';
+import PendingIcon from '../../../components/icons-components/PendingIcon';
import { translate } from '../../../helpers/l10n';
/*:: import type { Task } from '../types'; */
diff --git a/server/sonar-web/src/main/js/apps/code/components/App.js b/server/sonar-web/src/main/js/apps/code/components/App.js
index 3a0f994aa1c..c59cac6bade 100644
--- a/server/sonar-web/src/main/js/apps/code/components/App.js
+++ b/server/sonar-web/src/main/js/apps/code/components/App.js
@@ -20,7 +20,6 @@
import classNames from 'classnames';
import React from 'react';
import Helmet from 'react-helmet';
-import { connect } from 'react-redux';
import Components from './Components';
import Breadcrumbs from './Breadcrumbs';
import SourceViewer from './../../../components/SourceViewer/SourceViewer';
@@ -33,11 +32,10 @@ import {
parseError
} from '../utils';
import { addComponent, addComponentBreadcrumbs, clearBucket } from '../bucket';
-import { getComponent } from '../../../store/rootReducer';
import { translate } from '../../../helpers/l10n';
import '../code.css';
-class App extends React.PureComponent {
+export default class App extends React.PureComponent {
state = {
loading: true,
baseComponent: null,
@@ -75,7 +73,7 @@ class App extends React.PureComponent {
this.setState({ loading: true });
const isPortfolio = ['VW', 'SVW'].includes(component.qualifier);
- retrieveComponentChildren(component.key, isPortfolio)
+ retrieveComponentChildren(component.key, isPortfolio, component.branch)
.then(r => {
addComponent(r.baseComponent);
this.handleUpdate();
@@ -92,7 +90,7 @@ class App extends React.PureComponent {
this.setState({ loading: true });
const isPortfolio = ['VW', 'SVW'].includes(this.props.component.qualifier);
- retrieveComponent(componentKey, isPortfolio)
+ retrieveComponent(componentKey, isPortfolio, this.props.component.branch)
.then(r => {
if (this.mounted) {
if (['FIL', 'UTS'].includes(r.component.qualifier)) {
@@ -132,10 +130,10 @@ class App extends React.PureComponent {
this.loadComponent(finalKey);
}
- handleLoadMore() {
+ handleLoadMore = () => {
const { baseComponent, page } = this.state;
const isPortfolio = ['VW', 'SVW'].includes(this.props.component.qualifier);
- loadMoreChildren(baseComponent.key, page + 1, isPortfolio)
+ loadMoreChildren(baseComponent.key, page + 1, isPortfolio, this.props.component.branch)
.then(r => {
if (this.mounted) {
this.setState({
@@ -148,16 +146,16 @@ class App extends React.PureComponent {
.catch(e => {
if (this.mounted) {
this.setState({ loading: false });
- parseError(e).then(this.handleError.bind(this));
+ parseError(e).then(this.handleError);
}
});
- }
+ };
- handleError(error) {
+ handleError = error => {
if (this.mounted) {
this.setState({ error });
}
- }
+ };
render() {
const { component, location } = this.props;
@@ -186,7 +184,7 @@ class App extends React.PureComponent {
{error}
</div>}
- <Search location={location} component={component} onError={this.handleError.bind(this)} />
+ <Search location={location} component={component} onError={this.handleError} />
<div className="code-components">
{shouldShowBreadcrumbs &&
@@ -202,24 +200,14 @@ class App extends React.PureComponent {
</div>}
{shouldShowComponents &&
- <ListFooter
- count={components.length}
- total={total}
- loadMore={this.handleLoadMore.bind(this)}
- />}
+ <ListFooter count={components.length} total={total} loadMore={this.handleLoadMore} />}
{shouldShowSourceViewer &&
<div className="spacer-top">
- <SourceViewer component={sourceViewer.key} />
+ <SourceViewer branch={component.branch} component={sourceViewer.key} />
</div>}
</div>
</div>
);
}
}
-
-const mapStateToProps = (state, ownProps) => ({
- component: getComponent(state, ownProps.location.query.id)
-});
-
-export default connect(mapStateToProps)(App);
diff --git a/server/sonar-web/src/main/js/apps/code/components/Component.js b/server/sonar-web/src/main/js/apps/code/components/Component.js
index e36ad13bcf6..4fe40dfa618 100644
--- a/server/sonar-web/src/main/js/apps/code/components/Component.js
+++ b/server/sonar-web/src/main/js/apps/code/components/Component.js
@@ -70,10 +70,10 @@ export default class Component extends React.PureComponent {
switch (component.qualifier) {
case 'FIL':
case 'UTS':
- componentAction = <ComponentPin component={component} />;
+ componentAction = <ComponentPin branch={rootComponent.branch} component={component} />;
break;
default:
- componentAction = <ComponentDetach component={component} />;
+ componentAction = <ComponentDetach branch={rootComponent.branch} component={component} />;
}
}
diff --git a/server/sonar-web/src/main/js/apps/code/components/ComponentDetach.js b/server/sonar-web/src/main/js/apps/code/components/ComponentDetach.js
index 5277be98427..30fccdfa7bf 100644
--- a/server/sonar-web/src/main/js/apps/code/components/ComponentDetach.js
+++ b/server/sonar-web/src/main/js/apps/code/components/ComponentDetach.js
@@ -21,10 +21,10 @@ import React from 'react';
import { Link } from 'react-router';
import { translate } from '../../../helpers/l10n';
-export default function ComponentDetach({ component }) {
+export default function ComponentDetach({ component, branch }) {
return (
<Link
- to={{ pathname: '/dashboard', query: { id: component.refKey || component.key } }}
+ to={{ pathname: '/dashboard', query: { branch, id: component.refKey || component.key } }}
className="icon-detach"
title={translate('code.open_component_page')}
/>
diff --git a/server/sonar-web/src/main/js/apps/code/components/ComponentName.js b/server/sonar-web/src/main/js/apps/code/components/ComponentName.js
index bad7f487537..921aa3f724c 100644
--- a/server/sonar-web/src/main/js/apps/code/components/ComponentName.js
+++ b/server/sonar-web/src/main/js/apps/code/components/ComponentName.js
@@ -71,7 +71,7 @@ const ComponentName = ({ component, rootComponent, previous, canBrowse }) => {
</Link>
);
} else if (canBrowse) {
- const query = { id: rootComponent.key };
+ const query = { id: rootComponent.key, branch: rootComponent.branch };
if (component.key !== rootComponent.key) {
Object.assign(query, { selected: component.key });
}
diff --git a/server/sonar-web/src/main/js/apps/code/components/ComponentPin.js b/server/sonar-web/src/main/js/apps/code/components/ComponentPin.js
index 7d0f9478c59..641017207d7 100644
--- a/server/sonar-web/src/main/js/apps/code/components/ComponentPin.js
+++ b/server/sonar-web/src/main/js/apps/code/components/ComponentPin.js
@@ -22,10 +22,10 @@ import Workspace from '../../../components/workspace/main';
import PinIcon from '../../../components/shared/pin-icon';
import { translate } from '../../../helpers/l10n';
-const ComponentPin = ({ component }) => {
+const ComponentPin = ({ branch, component }) => {
const handleClick = e => {
e.preventDefault();
- Workspace.openComponent({ key: component.key });
+ Workspace.openComponent({ branch, key: component.key });
};
return (
diff --git a/server/sonar-web/src/main/js/apps/code/components/Search.js b/server/sonar-web/src/main/js/apps/code/components/Search.js
index a34d87e3c9e..4d772e7a3b1 100644
--- a/server/sonar-web/src/main/js/apps/code/components/Search.js
+++ b/server/sonar-web/src/main/js/apps/code/components/Search.js
@@ -46,7 +46,7 @@ export default class Search extends React.PureComponent {
};
componentWillMount() {
- this.handleSearch = debounce(this.handleSearch.bind(this), 250);
+ this.handleSearch = debounce(this.handleSearch, 250);
}
componentDidMount() {
@@ -100,6 +100,7 @@ export default class Search extends React.PureComponent {
this.context.router.push({
pathname: '/code',
query: {
+ branch: component.branch,
id: component.key,
selected: selected.key
}
@@ -126,7 +127,7 @@ export default class Search extends React.PureComponent {
}
}
- handleSearch(query) {
+ handleSearch = query => {
// first time check if value has changed due to debounce
if (this.mounted && this.checkInputValue(query)) {
const { component, onError } = this.props;
@@ -135,7 +136,12 @@ export default class Search extends React.PureComponent {
const isPortfolio = ['VW', 'SVW', 'APP'].includes(component.qualifier);
const qualifiers = isPortfolio ? 'SVW,TRK' : 'BRC,UTS,FIL';
- getTree(component.key, { q: query, s: 'qualifier,name', qualifiers })
+ getTree(component.key, {
+ branch: component.branch,
+ q: query,
+ s: 'qualifier,name',
+ qualifiers
+ })
.then(r => {
// second time check if value has change due to api request
if (this.mounted && this.checkInputValue(query)) {
@@ -154,7 +160,7 @@ export default class Search extends React.PureComponent {
}
});
}
- }
+ };
handleQueryChange(query) {
this.setState({ query });
diff --git a/server/sonar-web/src/main/js/apps/code/routes.ts b/server/sonar-web/src/main/js/apps/code/routes.ts
index fcffeff191c..9eb0b5ef7c3 100644
--- a/server/sonar-web/src/main/js/apps/code/routes.ts
+++ b/server/sonar-web/src/main/js/apps/code/routes.ts
@@ -22,7 +22,7 @@ import { RouterState, IndexRouteProps } from 'react-router';
const routes = [
{
getIndexRoute(_: RouterState, callback: (err: any, route: IndexRouteProps) => any) {
- import('./components/App').then(i => callback(null, { component: i.default }));
+ import('./components/App').then(i => callback(null, { component: (i as any).default }));
}
}
];
diff --git a/server/sonar-web/src/main/js/apps/code/utils.js b/server/sonar-web/src/main/js/apps/code/utils.js
index 2a1f5552cc0..52975be78ec 100644
--- a/server/sonar-web/src/main/js/apps/code/utils.js
+++ b/server/sonar-web/src/main/js/apps/code/utils.js
@@ -120,7 +120,7 @@ function getMetrics(isPortfolio) {
* @param {boolean} isPortfolio
* @returns {Promise}
*/
-function retrieveComponentBase(componentKey, isPortfolio) {
+function retrieveComponentBase(componentKey, isPortfolio, branch) {
const existing = getComponentFromBucket(componentKey);
if (existing) {
return Promise.resolve(existing);
@@ -128,7 +128,7 @@ function retrieveComponentBase(componentKey, isPortfolio) {
const metrics = getMetrics(isPortfolio);
- return getComponent(componentKey, metrics).then(component => {
+ return getComponent(componentKey, metrics, branch).then(component => {
addComponent(component);
return component;
});
@@ -139,7 +139,7 @@ function retrieveComponentBase(componentKey, isPortfolio) {
* @param {boolean} isPortfolio
* @returns {Promise}
*/
-export function retrieveComponentChildren(componentKey, isPortfolio) {
+export function retrieveComponentChildren(componentKey, isPortfolio, branch) {
const existing = getComponentChildren(componentKey);
if (existing) {
return Promise.resolve({
@@ -151,7 +151,7 @@ export function retrieveComponentChildren(componentKey, isPortfolio) {
const metrics = getMetrics(isPortfolio);
- return getChildren(componentKey, metrics, { ps: PAGE_SIZE, s: 'qualifier,name' })
+ return getChildren(componentKey, metrics, { branch, ps: PAGE_SIZE, s: 'qualifier,name' })
.then(prepareChildren)
.then(expandRootDir(metrics))
.then(r => {
@@ -162,13 +162,13 @@ export function retrieveComponentChildren(componentKey, isPortfolio) {
});
}
-function retrieveComponentBreadcrumbs(componentKey) {
+function retrieveComponentBreadcrumbs(componentKey, branch) {
const existing = getComponentBreadcrumbs(componentKey);
if (existing) {
return Promise.resolve(existing);
}
- return getBreadcrumbs(componentKey).then(skipRootDir).then(breadcrumbs => {
+ return getBreadcrumbs(componentKey, branch).then(skipRootDir).then(breadcrumbs => {
addComponentBreadcrumbs(componentKey, breadcrumbs);
return breadcrumbs;
});
@@ -179,11 +179,11 @@ function retrieveComponentBreadcrumbs(componentKey) {
* @param {boolean} isPortfolio
* @returns {Promise}
*/
-export function retrieveComponent(componentKey, isPortfolio) {
+export function retrieveComponent(componentKey, isPortfolio, branch) {
return Promise.all([
- retrieveComponentBase(componentKey, isPortfolio),
- retrieveComponentChildren(componentKey, isPortfolio),
- retrieveComponentBreadcrumbs(componentKey)
+ retrieveComponentBase(componentKey, isPortfolio, branch),
+ retrieveComponentChildren(componentKey, isPortfolio, branch),
+ retrieveComponentBreadcrumbs(componentKey, branch)
]).then(r => {
return {
component: r[0],
@@ -195,10 +195,10 @@ export function retrieveComponent(componentKey, isPortfolio) {
});
}
-export function loadMoreChildren(componentKey, page, isPortfolio) {
+export function loadMoreChildren(componentKey, page, isPortfolio, branch) {
const metrics = getMetrics(isPortfolio);
- return getChildren(componentKey, metrics, { ps: PAGE_SIZE, p: page })
+ return getChildren(componentKey, metrics, { branch, ps: PAGE_SIZE, p: page })
.then(prepareChildren)
.then(expandRootDir(metrics))
.then(r => {
diff --git a/server/sonar-web/src/main/js/apps/component-measures/components/AppContainer.js b/server/sonar-web/src/main/js/apps/component-measures/components/AppContainer.js
index f3d91451c47..f823961bb6f 100644
--- a/server/sonar-web/src/main/js/apps/component-measures/components/AppContainer.js
+++ b/server/sonar-web/src/main/js/apps/component-measures/components/AppContainer.js
@@ -22,12 +22,7 @@ import { connect } from 'react-redux';
import { withRouter } from 'react-router';
import App from './App';
import throwGlobalError from '../../../app/utils/throwGlobalError';
-import {
- getComponent,
- getCurrentUser,
- getMetrics,
- getMetricsKey
-} from '../../../store/rootReducer';
+import { getCurrentUser, getMetrics, getMetricsKey } from '../../../store/rootReducer';
import { fetchMetrics } from '../../../store/rootActions';
import { getMeasuresAndMeta } from '../../../api/measures';
import { getLeakPeriod } from '../../../helpers/periods';
@@ -35,8 +30,7 @@ import { enhanceMeasure } from '../../../components/measure/utils';
/*:: import type { Component, Period } from '../types'; */
/*:: import type { Measure, MeasureEnhanced } from '../../../components/measure/types'; */
-const mapStateToProps = (state, ownProps) => ({
- component: getComponent(state, ownProps.location.query.id),
+const mapStateToProps = state => ({
currentUser: getCurrentUser(state),
metrics: getMetrics(state),
metricsKey: getMetricsKey(state)
diff --git a/server/sonar-web/src/main/js/apps/custom-measures/components/CustomMeasuresAppContainer.js b/server/sonar-web/src/main/js/apps/custom-measures/components/CustomMeasuresAppContainer.js
index 1f40c41775f..4f2f1ba1ca6 100644
--- a/server/sonar-web/src/main/js/apps/custom-measures/components/CustomMeasuresAppContainer.js
+++ b/server/sonar-web/src/main/js/apps/custom-measures/components/CustomMeasuresAppContainer.js
@@ -19,12 +19,10 @@
*/
import React from 'react';
import Helmet from 'react-helmet';
-import { connect } from 'react-redux';
import init from '../init';
-import { getComponent } from '../../../store/rootReducer';
import { translate } from '../../../helpers/l10n';
-class CustomMeasuresAppContainer extends React.PureComponent {
+export default class CustomMeasuresAppContainer extends React.PureComponent {
componentDidMount() {
init(this.refs.container, this.props.component);
}
@@ -38,9 +36,3 @@ class CustomMeasuresAppContainer extends React.PureComponent {
);
}
}
-
-const mapStateToProps = (state, ownProps) => ({
- component: getComponent(state, ownProps.location.query.id)
-});
-
-export default connect(mapStateToProps)(CustomMeasuresAppContainer);
diff --git a/server/sonar-web/src/main/js/apps/custom-measures/routes.ts b/server/sonar-web/src/main/js/apps/custom-measures/routes.ts
index ad092ba1d48..cc0a32c95c1 100644
--- a/server/sonar-web/src/main/js/apps/custom-measures/routes.ts
+++ b/server/sonar-web/src/main/js/apps/custom-measures/routes.ts
@@ -23,7 +23,7 @@ const routes = [
{
getIndexRoute(_: RouterState, callback: (err: any, route: IndexRouteProps) => any) {
import('./components/CustomMeasuresAppContainer').then(i =>
- callback(null, { component: i.default })
+ callback(null, { component: (i as any).default })
);
}
}
diff --git a/server/sonar-web/src/main/js/apps/issues/components/App.js b/server/sonar-web/src/main/js/apps/issues/components/App.js
index 4a0040f2991..509a69dddce 100644
--- a/server/sonar-web/src/main/js/apps/issues/components/App.js
+++ b/server/sonar-web/src/main/js/apps/issues/components/App.js
@@ -63,6 +63,7 @@ import '../styles.css';
/*::
export type Props = {
+ branch?: { name: string },
component?: Component,
currentUser: CurrentUser,
fetchIssues: (query: RawQuery) => Promise<*>,
@@ -171,6 +172,7 @@ export default class App extends React.PureComponent {
const { query } = this.props.location;
const { query: prevQuery } = prevProps.location;
if (
+ prevProps.component !== this.props.component ||
!areQueriesEqual(prevQuery, query) ||
areMyIssuesSelected(prevQuery) !== areMyIssuesSelected(query)
) {
@@ -306,6 +308,7 @@ export default class App extends React.PureComponent {
pathname: this.props.location.pathname,
query: {
...serializeQuery(this.state.query),
+ branch: this.props.branch && this.props.branch.name,
id: this.props.component && this.props.component.key,
myIssues: this.state.myIssues ? 'true' : undefined,
open: issue
@@ -324,6 +327,7 @@ export default class App extends React.PureComponent {
pathname: this.props.location.pathname,
query: {
...serializeQuery(this.state.query),
+ branch: this.props.branch && this.props.branch.name,
id: this.props.component && this.props.component.key,
myIssues: this.state.myIssues ? 'true' : undefined,
open: undefined
@@ -359,6 +363,8 @@ export default class App extends React.PureComponent {
: undefined;
const parameters = {
+ branch: this.props.branch && this.props.branch.name,
+ componentKeys: component && component.key,
s: 'FILE_LINE',
...serializeQuery(query),
ps: '100',
@@ -367,10 +373,6 @@ export default class App extends React.PureComponent {
...additional
};
- if (component) {
- Object.assign(parameters, { componentKeys: component.key });
- }
-
// only sorting by CREATION_DATE is allowed, so let's sort DESC
if (query.sort) {
Object.assign(parameters, { asc: 'false' });
@@ -552,6 +554,7 @@ export default class App extends React.PureComponent {
pathname: this.props.location.pathname,
query: {
...serializeQuery({ ...this.state.query, ...changes }),
+ branch: this.props.branch && this.props.branch.name,
id: this.props.component && this.props.component.key,
myIssues: this.state.myIssues ? 'true' : undefined
}
@@ -567,6 +570,7 @@ export default class App extends React.PureComponent {
pathname: this.props.location.pathname,
query: {
...serializeQuery({ ...this.state.query, assigned: true, assignees: [] }),
+ branch: this.props.branch && this.props.branch.name,
id: this.props.component && this.props.component.key,
myIssues: myIssues ? 'true' : undefined
}
@@ -593,6 +597,7 @@ export default class App extends React.PureComponent {
pathname: this.props.location.pathname,
query: {
...DEFAULT_QUERY,
+ branch: this.props.branch && this.props.branch.name,
id: this.props.component && this.props.component.key,
myIssues: this.state.myIssues ? 'true' : undefined
}
@@ -885,6 +890,8 @@ export default class App extends React.PureComponent {
<div>
{openIssue
? <IssuesSourceViewer
+ branch={this.props.branch}
+ component={component}
openIssue={openIssue}
loadIssues={this.fetchIssuesForComponent}
onIssueChange={this.handleIssueChange}
diff --git a/server/sonar-web/src/main/js/apps/issues/components/AppContainer.js b/server/sonar-web/src/main/js/apps/issues/components/AppContainer.js
index 040f0c4718f..2f6b4368a87 100644
--- a/server/sonar-web/src/main/js/apps/issues/components/AppContainer.js
+++ b/server/sonar-web/src/main/js/apps/issues/components/AppContainer.js
@@ -24,17 +24,14 @@ import { withRouter } from 'react-router';
import { uniq } from 'lodash';
import App from './App';
import throwGlobalError from '../../../app/utils/throwGlobalError';
-import { getComponent, getCurrentUser } from '../../../store/rootReducer';
+import { getCurrentUser } from '../../../store/rootReducer';
import { getOrganizations } from '../../../api/organizations';
import { receiveOrganizations } from '../../../store/organizations/duck';
import { searchIssues } from '../../../api/issues';
import { parseIssueFromResponse } from '../../../helpers/issues';
/*:: import type { RawQuery } from '../../../helpers/query'; */
-const mapStateToProps = (state, ownProps) => ({
- component: ownProps.location.query.id
- ? getComponent(state, ownProps.location.query.id)
- : undefined,
+const mapStateToProps = state => ({
currentUser: getCurrentUser(state)
});
diff --git a/server/sonar-web/src/main/js/apps/issues/components/IssuesSourceViewer.js b/server/sonar-web/src/main/js/apps/issues/components/IssuesSourceViewer.js
index 498f2e377ce..6561fd547fa 100644
--- a/server/sonar-web/src/main/js/apps/issues/components/IssuesSourceViewer.js
+++ b/server/sonar-web/src/main/js/apps/issues/components/IssuesSourceViewer.js
@@ -21,10 +21,13 @@
import React from 'react';
import SourceViewer from '../../../components/SourceViewer/SourceViewer';
import { scrollToElement } from '../../../helpers/scrolling';
+/*:: import type { Component, } from '../utils'; */
/*:: import type { Issue } from '../../../components/issue/types'; */
/*::
type Props = {|
+ branch?: { name: string },
+ component: Component,
loadIssues: (string, number, number) => Promise<*>,
onIssueChange: Issue => void,
onIssueSelect: string => void,
@@ -83,6 +86,7 @@ export default class IssuesSourceViewer extends React.PureComponent {
<div ref={node => (this.node = node)}>
<SourceViewer
aroundLine={openIssue.textRange ? openIssue.textRange.endLine : undefined}
+ branch={this.props.branch && this.props.branch.name}
component={openIssue.component}
displayAllIssues={true}
highlightedLocations={locations}
diff --git a/server/sonar-web/src/main/js/apps/issues/sidebar/CreationDateFacet.js b/server/sonar-web/src/main/js/apps/issues/sidebar/CreationDateFacet.js
index 6170138afa2..95174567951 100644
--- a/server/sonar-web/src/main/js/apps/issues/sidebar/CreationDateFacet.js
+++ b/server/sonar-web/src/main/js/apps/issues/sidebar/CreationDateFacet.js
@@ -215,6 +215,10 @@ export default class CreationDateFacet extends React.PureComponent {
renderPredefinedPeriods() {
const { component, createdInLast, sinceLeakPeriod } = this.props;
+ if (component != null && component.branch != null) {
+ // FIXME handle long-living branches
+ return null;
+ }
return (
<div className="spacer-top issues-predefined-periods">
<FacetItem
diff --git a/server/sonar-web/src/main/js/apps/overview/components/App.js b/server/sonar-web/src/main/js/apps/overview/components/App.js
index 37e04ee3742..aa36f8402aa 100644
--- a/server/sonar-web/src/main/js/apps/overview/components/App.js
+++ b/server/sonar-web/src/main/js/apps/overview/components/App.js
@@ -22,10 +22,13 @@ import React from 'react';
import PropTypes from 'prop-types';
import OverviewApp from './OverviewApp';
import EmptyOverview from './EmptyOverview';
+import { isShortLivingBranch } from '../../../helpers/branches';
+import { getProjectBranchUrl } from '../../../helpers/urls';
import SourceViewer from '../../../components/SourceViewer/SourceViewer';
/*::
type Props = {
+ branch: {},
component: {
analysisDate?: string,
id: string,
@@ -33,6 +36,7 @@ type Props = {
qualifier: string,
tags: Array<string>
},
+ onComponentChange: {} => void,
router: Object
};
*/
@@ -52,6 +56,9 @@ export default class App extends React.PureComponent {
query: { id: this.props.component.key }
});
}
+ if (isShortLivingBranch(this.props.branch)) {
+ this.context.router.replace(getProjectBranchUrl(this.props.component.key, this.props.branch));
+ }
}
isPortfolio() {
@@ -59,7 +66,7 @@ export default class App extends React.PureComponent {
}
render() {
- if (this.isPortfolio()) {
+ if (this.isPortfolio() || isShortLivingBranch(this.props.branch)) {
return null;
}
@@ -77,6 +84,6 @@ export default class App extends React.PureComponent {
return <EmptyOverview component={component} />;
}
- return <OverviewApp component={component} />;
+ return <OverviewApp component={component} onComponentChange={this.props.onComponentChange} />;
}
}
diff --git a/server/sonar-web/src/main/js/apps/overview/components/AppContainer.js b/server/sonar-web/src/main/js/apps/overview/components/AppContainer.js
deleted file mode 100644
index a6025ae8fe4..00000000000
--- a/server/sonar-web/src/main/js/apps/overview/components/AppContainer.js
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * 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.
- */
-import { connect } from 'react-redux';
-import App from './App';
-import { getComponent } from '../../../store/rootReducer';
-
-const mapStateToProps = (state, ownProps) => ({
- component: getComponent(state, ownProps.location.query.id)
-});
-
-export default connect(mapStateToProps)(App);
diff --git a/server/sonar-web/src/main/js/apps/overview/components/OverviewApp.js b/server/sonar-web/src/main/js/apps/overview/components/OverviewApp.js
index ac67fbae194..9e28bf48386 100644
--- a/server/sonar-web/src/main/js/apps/overview/components/OverviewApp.js
+++ b/server/sonar-web/src/main/js/apps/overview/components/OverviewApp.js
@@ -41,7 +41,8 @@ import '../styles.css';
/*::
type Props = {
- component: Component
+ component: Component,
+ onComponentChange: {} => void
};
*/
@@ -175,7 +176,12 @@ export default class OverviewApp extends React.PureComponent {
</div>
<div className="page-sidebar-fixed">
- <Meta component={component} history={history} measures={measures} />
+ <Meta
+ component={component}
+ history={history}
+ measures={measures}
+ onComponentChange={this.props.onComponentChange}
+ />
</div>
</div>
</div>
diff --git a/server/sonar-web/src/main/js/apps/overview/meta/Meta.js b/server/sonar-web/src/main/js/apps/overview/meta/Meta.js
index fd849228480..a79b44dbd41 100644
--- a/server/sonar-web/src/main/js/apps/overview/meta/Meta.js
+++ b/server/sonar-web/src/main/js/apps/overview/meta/Meta.js
@@ -30,7 +30,14 @@ import MetaSize from './MetaSize';
import MetaTags from './MetaTags';
import { areThereCustomOrganizations } from '../../../store/rootReducer';
-const Meta = ({ component, history, measures, areThereCustomOrganizations, router }) => {
+const Meta = ({
+ component,
+ history,
+ measures,
+ areThereCustomOrganizations,
+ onComponentChange,
+ router
+}) => {
const { qualifier, description, qualityProfiles, qualityGate } = component;
const isProject = qualifier === 'TRK';
@@ -53,7 +60,7 @@ const Meta = ({ component, history, measures, areThereCustomOrganizations, route
<MetaSize component={component} measures={measures} />
- {isProject && <MetaTags component={component} />}
+ {isProject && <MetaTags component={component} onComponentChange={onComponentChange} />}
{(isProject || isApplication) &&
<AnalysesList
diff --git a/server/sonar-web/src/main/js/apps/overview/meta/MetaTags.js b/server/sonar-web/src/main/js/apps/overview/meta/MetaTags.js
index b9d67b8e474..7254f0e2197 100644
--- a/server/sonar-web/src/main/js/apps/overview/meta/MetaTags.js
+++ b/server/sonar-web/src/main/js/apps/overview/meta/MetaTags.js
@@ -19,9 +19,10 @@
*/
//@flow
import React from 'react';
+import { setProjectTags } from '../../../api/components';
import { translate } from '../../../helpers/l10n';
import TagsList from '../../../components/tags/TagsList';
-import ProjectTagsSelectorContainer from '../../projects/components/ProjectTagsSelectorContainer';
+import MetaTagsSelector from './MetaTagsSelector';
/*::
type Props = {
@@ -31,7 +32,8 @@ type Props = {
configuration?: {
showSettings?: boolean
}
- }
+ },
+ onComponentChange: {} => void
};
*/
@@ -104,6 +106,13 @@ export default class MetaTags extends React.PureComponent {
};
}
+ handleSetProjectTags = (tags /*: Array<string> */) => {
+ setProjectTags({ project: this.props.component.key, tags: tags.join(',') }).then(
+ () => this.props.onComponentChange({ tags }),
+ () => {}
+ );
+ };
+
render() {
const { tags, key } = this.props.component;
const { popupOpen, popupPosition } = this.state;
@@ -119,10 +128,11 @@ export default class MetaTags extends React.PureComponent {
</button>
{popupOpen &&
<div ref={tagsSelector => (this.tagsSelector = tagsSelector)}>
- <ProjectTagsSelectorContainer
+ <MetaTagsSelector
position={popupPosition}
project={key}
selectedTags={tags}
+ setProjectTags={this.handleSetProjectTags}
/>
</div>}
</div>
diff --git a/server/sonar-web/src/main/js/apps/projects/components/ProjectTagsSelectorContainer.js b/server/sonar-web/src/main/js/apps/overview/meta/MetaTagsSelector.js
index 2cb4ab4e54a..76e25c9c1f1 100644
--- a/server/sonar-web/src/main/js/apps/projects/components/ProjectTagsSelectorContainer.js
+++ b/server/sonar-web/src/main/js/apps/overview/meta/MetaTagsSelector.js
@@ -19,18 +19,16 @@
*/
//@flow
import React from 'react';
-import { connect } from 'react-redux';
import { debounce, without } from 'lodash';
import TagsSelector from '../../../components/tags/TagsSelector';
import { searchProjectTags } from '../../../api/components';
-import { setProjectTags } from '../store/actions';
/*::
type Props = {
position: {},
project: string,
selectedTags: Array<string>,
- setProjectTags: (string, Array<string>) => void
+ setProjectTags: (Array<string>) => void
};
*/
@@ -42,7 +40,7 @@ type State = {
const LIST_SIZE = 10;
-class ProjectTagsSelectorContainer extends React.PureComponent {
+export default class MetaTagsSelector extends React.PureComponent {
/*:: props: Props; */
/*:: state: State; */
@@ -68,11 +66,11 @@ class ProjectTagsSelectorContainer extends React.PureComponent {
};
onSelect = (tag /*: string */) => {
- this.props.setProjectTags(this.props.project, [...this.props.selectedTags, tag]);
+ this.props.setProjectTags([...this.props.selectedTags, tag]);
};
onUnselect = (tag /*: string */) => {
- this.props.setProjectTags(this.props.project, without(this.props.selectedTags, tag));
+ this.props.setProjectTags(without(this.props.selectedTags, tag));
};
render() {
@@ -89,5 +87,3 @@ class ProjectTagsSelectorContainer extends React.PureComponent {
);
}
}
-
-export default connect(null, { setProjectTags })(ProjectTagsSelectorContainer);
diff --git a/server/sonar-web/src/main/js/apps/overview/meta/__tests__/MetaTagsSelector-test.js b/server/sonar-web/src/main/js/apps/overview/meta/__tests__/MetaTagsSelector-test.js
new file mode 100644
index 00000000000..59744a204de
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/overview/meta/__tests__/MetaTagsSelector-test.js
@@ -0,0 +1,61 @@
+/*
+ * 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.
+ */
+/* eslint-disable import/order, import/first */
+import * as React from 'react';
+import { mount, shallow } from 'enzyme';
+import MetaTagsSelector from '../MetaTagsSelector';
+
+jest.mock('../../../../api/components', () => ({
+ searchProjectTags: jest.fn()
+}));
+
+jest.useFakeTimers();
+
+import { searchProjectTags } from '../../../../api/components';
+
+it('searches tags on mount', () => {
+ searchProjectTags.mockImplementation(() => Promise.resolve({ tags: ['foo', 'bar'] }));
+
+ mount(
+ <MetaTagsSelector position={{}} project="foo" selectedTags={[]} setProjectTags={jest.fn()} />
+ );
+ jest.runAllTimers();
+
+ expect(searchProjectTags).toBeCalledWith({ ps: 9, q: '' });
+});
+
+it('selects and deselects tags', () => {
+ const setProjectTags = jest.fn();
+ const wrapper = shallow(
+ <MetaTagsSelector
+ position={{}}
+ project="foo"
+ selectedTags={['foo', 'bar']}
+ setProjectTags={setProjectTags}
+ />
+ );
+
+ wrapper.find('TagsSelector').prop('onSelect')('baz');
+ expect(setProjectTags).toHaveBeenLastCalledWith(['foo', 'bar', 'baz']);
+
+ // note that the `selectedTags` is a prop and so it wasn't changed
+ wrapper.find('TagsSelector').prop('onUnselect')('bar');
+ expect(setProjectTags).toHaveBeenLastCalledWith(['foo']);
+});
diff --git a/server/sonar-web/src/main/js/apps/overview/meta/__tests__/__snapshots__/MetaTags-test.js.snap b/server/sonar-web/src/main/js/apps/overview/meta/__tests__/__snapshots__/MetaTags-test.js.snap
index 0eb1415ab03..875302462d5 100644
--- a/server/sonar-web/src/main/js/apps/overview/meta/__tests__/__snapshots__/MetaTags-test.js.snap
+++ b/server/sonar-web/src/main/js/apps/overview/meta/__tests__/__snapshots__/MetaTags-test.js.snap
@@ -40,7 +40,7 @@ exports[`should open the tag selector on click 2`] = `
/>
</button>
<div>
- <Connect(ProjectTagsSelectorContainer)
+ <MetaTagsSelector
position={
Object {
"right": 0,
@@ -54,6 +54,7 @@ exports[`should open the tag selector on click 2`] = `
"bar",
]
}
+ setProjectTags={[Function]}
/>
</div>
</div>
diff --git a/server/sonar-web/src/main/js/apps/overview/routes.ts b/server/sonar-web/src/main/js/apps/overview/routes.ts
index 21e41c6b087..9eb0b5ef7c3 100644
--- a/server/sonar-web/src/main/js/apps/overview/routes.ts
+++ b/server/sonar-web/src/main/js/apps/overview/routes.ts
@@ -22,7 +22,7 @@ import { RouterState, IndexRouteProps } from 'react-router';
const routes = [
{
getIndexRoute(_: RouterState, callback: (err: any, route: IndexRouteProps) => any) {
- import('./components/AppContainer').then(i => callback(null, { component: i.default }));
+ import('./components/App').then(i => callback(null, { component: (i as any).default }));
}
}
];
diff --git a/server/sonar-web/src/main/js/apps/project-admin/deletion/Deletion.js b/server/sonar-web/src/main/js/apps/project-admin/deletion/Deletion.js
index 5aff00dd956..9cd6a47ea96 100644
--- a/server/sonar-web/src/main/js/apps/project-admin/deletion/Deletion.js
+++ b/server/sonar-web/src/main/js/apps/project-admin/deletion/Deletion.js
@@ -18,36 +18,17 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import React from 'react';
-import PropTypes from 'prop-types';
import Helmet from 'react-helmet';
-import { connect } from 'react-redux';
import Header from './Header';
import Form from './Form';
-import { getComponent } from '../../../store/rootReducer';
import { translate } from '../../../helpers/l10n';
-class Deletion extends React.PureComponent {
- static propTypes = {
- component: PropTypes.object
- };
-
- render() {
- if (!this.props.component) {
- return null;
- }
-
- return (
- <div className="page page-limited">
- <Helmet title={translate('deletion.page')} />
- <Header component={this.props.component} />
- <Form component={this.props.component} />
- </div>
- );
- }
+export default function Deletion(props) {
+ return (
+ <div className="page page-limited">
+ <Helmet title={translate('deletion.page')} />
+ <Header component={props.component} />
+ <Form component={props.component} />
+ </div>
+ );
}
-
-const mapStateToProps = (state, ownProps) => ({
- component: getComponent(state, ownProps.location.query.id)
-});
-
-export default connect(mapStateToProps)(Deletion);
diff --git a/server/sonar-web/src/main/js/apps/project-admin/key/Key.js b/server/sonar-web/src/main/js/apps/project-admin/key/Key.js
index 130d67cd4c2..4a340ab6371 100644
--- a/server/sonar-web/src/main/js/apps/project-admin/key/Key.js
+++ b/server/sonar-web/src/main/js/apps/project-admin/key/Key.js
@@ -35,11 +35,11 @@ import {
import { parseError } from '../../code/utils';
import { reloadUpdateKeyPage } from './utils';
import RecentHistory from '../../../app/components/RecentHistory';
-import { getProjectAdminProjectModules, getComponent } from '../../../store/rootReducer';
+import { getProjectAdminProjectModules } from '../../../store/rootReducer';
class Key extends React.PureComponent {
static propTypes = {
- component: PropTypes.object.isRequired,
+ component: PropTypes.object,
fetchProjectModules: PropTypes.func.isRequired,
changeKey: PropTypes.func.isRequired,
addGlobalErrorMessage: PropTypes.func.isRequired,
@@ -141,7 +141,6 @@ class Key extends React.PureComponent {
}
const mapStateToProps = (state, ownProps) => ({
- component: getComponent(state, ownProps.location.query.id),
modules: getProjectAdminProjectModules(state, ownProps.location.query.id)
});
diff --git a/server/sonar-web/src/main/js/apps/project-admin/links/Links.js b/server/sonar-web/src/main/js/apps/project-admin/links/Links.js
index fede0404e07..592ae5fc092 100644
--- a/server/sonar-web/src/main/js/apps/project-admin/links/Links.js
+++ b/server/sonar-web/src/main/js/apps/project-admin/links/Links.js
@@ -25,12 +25,12 @@ import Header from './Header';
import Table from './Table';
import DeletionModal from './views/DeletionModal';
import { fetchProjectLinks, deleteProjectLink, createProjectLink } from '../store/actions';
-import { getProjectAdminProjectLinks, getComponent } from '../../../store/rootReducer';
+import { getProjectAdminProjectLinks } from '../../../store/rootReducer';
import { translate } from '../../../helpers/l10n';
class Links extends React.PureComponent {
static propTypes = {
- component: PropTypes.object.isRequired,
+ component: PropTypes.object,
links: PropTypes.array
};
@@ -67,7 +67,6 @@ class Links extends React.PureComponent {
}
const mapStateToProps = (state, ownProps) => ({
- component: getComponent(state, ownProps.location.query.id),
links: getProjectAdminProjectLinks(state, ownProps.location.query.id)
});
diff --git a/server/sonar-web/src/main/js/apps/project-admin/quality-gate/QualityGate.js b/server/sonar-web/src/main/js/apps/project-admin/quality-gate/QualityGate.js
index f07fbed428b..6194c04371a 100644
--- a/server/sonar-web/src/main/js/apps/project-admin/quality-gate/QualityGate.js
+++ b/server/sonar-web/src/main/js/apps/project-admin/quality-gate/QualityGate.js
@@ -24,16 +24,12 @@ import { connect } from 'react-redux';
import Header from './Header';
import Form from './Form';
import { fetchProjectGate, setProjectGate } from '../store/actions';
-import {
- getProjectAdminAllGates,
- getProjectAdminProjectGate,
- getComponent
-} from '../../../store/rootReducer';
+import { getProjectAdminAllGates, getProjectAdminProjectGate } from '../../../store/rootReducer';
import { translate } from '../../../helpers/l10n';
class QualityGate extends React.PureComponent {
static propTypes = {
- component: PropTypes.object.isRequired,
+ component: PropTypes.object,
allGates: PropTypes.array,
gate: PropTypes.object
};
@@ -62,7 +58,6 @@ class QualityGate extends React.PureComponent {
}
const mapStateToProps = (state, ownProps) => ({
- component: getComponent(state, ownProps.location.query.id),
allGates: getProjectAdminAllGates(state),
gate: getProjectAdminProjectGate(state, ownProps.location.query.id)
});
diff --git a/server/sonar-web/src/main/js/apps/project-admin/quality-profiles/QualityProfiles.js b/server/sonar-web/src/main/js/apps/project-admin/quality-profiles/QualityProfiles.js
index 4551f410a25..02ff3c3eac5 100644
--- a/server/sonar-web/src/main/js/apps/project-admin/quality-profiles/QualityProfiles.js
+++ b/server/sonar-web/src/main/js/apps/project-admin/quality-profiles/QualityProfiles.js
@@ -27,8 +27,7 @@ import { fetchProjectProfiles, setProjectProfile } from '../store/actions';
import {
areThereCustomOrganizations,
getProjectAdminAllProfiles,
- getProjectAdminProjectProfiles,
- getComponent
+ getProjectAdminProjectProfiles
} from '../../../store/rootReducer';
import { translate } from '../../../helpers/l10n';
@@ -80,7 +79,6 @@ class QualityProfiles extends React.PureComponent {
}
const mapStateToProps = (state, ownProps) => ({
- component: getComponent(state, ownProps.location.query.id),
customOrganizations: areThereCustomOrganizations(state),
allProfiles: getProjectAdminAllProfiles(state),
profiles: getProjectAdminProjectProfiles(state, ownProps.location.query.id)
diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityAppContainer.js b/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityAppContainer.js
index 1d3c9845ecd..de7cde52b7a 100644
--- a/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityAppContainer.js
+++ b/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityAppContainer.js
@@ -19,11 +19,9 @@
*/
// @flow
import React from 'react';
-import { connect } from 'react-redux';
-import { withRouter } from 'react-router';
+import PropTypes from 'prop-types';
import ProjectActivityApp from './ProjectActivityApp';
import throwGlobalError from '../../../app/utils/throwGlobalError';
-import { getComponent } from '../../../store/rootReducer';
import { getAllTimeMachineData } from '../../../api/time-machine';
import { getMetrics } from '../../../api/metrics';
import * as api from '../../../api/projectActivity';
@@ -45,15 +43,11 @@ import {
/*::
type Props = {
location: { pathname: string, query: RawQuery },
- project: {
+ component: {
configuration?: { showHistory: boolean },
key: string,
leakPeriodDate: string,
qualifier: string
- },
- router: {
- push: ({ pathname: string, query?: RawQuery }) => void,
- replace: ({ pathname: string, query?: RawQuery }) => void
}
};
*/
@@ -71,11 +65,15 @@ export type State = {
};
*/
-class ProjectActivityAppContainer extends React.PureComponent {
+export default class ProjectActivityAppContainer extends React.PureComponent {
/*:: mounted: boolean; */
/*:: props: Props; */
/*:: state: State; */
+ static contextTypes = {
+ router: PropTypes.object
+ };
+
constructor(props /*: Props */) {
super(props);
this.state = {
@@ -93,7 +91,7 @@ class ProjectActivityAppContainer extends React.PureComponent {
if (isCustomGraph(newQuery.graph)) {
newQuery.customMetrics = getCustomGraph();
}
- this.props.router.replace({
+ this.context.router.replace({
pathname: props.location.pathname,
query: serializeUrlQuery(newQuery)
});
@@ -182,7 +180,7 @@ class ProjectActivityAppContainer extends React.PureComponent {
if (metrics.length <= 0) {
return Promise.resolve([]);
}
- return getAllTimeMachineData(this.props.project.key, metrics).then(
+ return getAllTimeMachineData(this.props.component.key, metrics).then(
({ measures }) =>
measures.map(measure => ({
metric: measure.metric,
@@ -279,11 +277,11 @@ class ProjectActivityAppContainer extends React.PureComponent {
...this.state.query,
...newQuery
});
- this.props.router.push({
+ this.context.router.push({
pathname: this.props.location.pathname,
query: {
...query,
- id: this.props.project.key
+ id: this.props.component.key
}
});
};
@@ -319,16 +317,10 @@ class ProjectActivityAppContainer extends React.PureComponent {
initializing={!this.state.initialized}
metrics={this.state.metrics}
measuresHistory={this.state.measuresHistory}
- project={this.props.project}
+ project={this.props.component}
query={this.state.query}
updateQuery={this.updateQuery}
/>
);
}
}
-
-const mapStateToProps = (state, ownProps) => ({
- project: getComponent(state, ownProps.location.query.id)
-});
-
-export default connect(mapStateToProps)(withRouter(ProjectActivityAppContainer));
diff --git a/server/sonar-web/src/main/js/apps/projectActivity/routes.ts b/server/sonar-web/src/main/js/apps/projectActivity/routes.ts
index 47d7bda3dae..8641ea7391c 100644
--- a/server/sonar-web/src/main/js/apps/projectActivity/routes.ts
+++ b/server/sonar-web/src/main/js/apps/projectActivity/routes.ts
@@ -23,7 +23,7 @@ const routes = [
{
getIndexRoute(_: RouterState, callback: (err: any, route: IndexRouteProps) => any) {
import('./components/ProjectActivityAppContainer').then(i =>
- callback(null, { component: i.default })
+ callback(null, { component: (i as any).default })
);
}
}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/AppContainer.js b/server/sonar-web/src/main/js/apps/settings/components/AppContainer.js
index 8e80ca6cb6f..cbc69d53cfa 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/AppContainer.js
+++ b/server/sonar-web/src/main/js/apps/settings/components/AppContainer.js
@@ -20,12 +20,9 @@
import { connect } from 'react-redux';
import App from './App';
import { fetchSettings } from '../store/actions';
-import { getComponent, getSettingsAppDefaultCategory } from '../../../store/rootReducer';
+import { getSettingsAppDefaultCategory } from '../../../store/rootReducer';
-const mapStateToProps = (state, ownProps) => ({
- component: ownProps.location.query.id
- ? getComponent(state, ownProps.location.query.id)
- : undefined,
+const mapStateToProps = state => ({
defaultCategory: getSettingsAppDefaultCategory(state)
});