@@ -18,7 +18,7 @@ | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import * as React from 'react'; | |||
import ProjectContainerNotFound from './ProjectContainerNotFound'; | |||
import ComponentContainerNotFound from './ComponentContainerNotFound'; | |||
import ComponentNav from './nav/component/ComponentNav'; | |||
import { Branch, Component } from '../types'; | |||
import handleRequiredAuthorization from '../utils/handleRequiredAuthorization'; | |||
@@ -39,7 +39,7 @@ interface State { | |||
component: Component | null; | |||
} | |||
export default class ProjectContainer extends React.PureComponent<Props, State> { | |||
export default class ComponentContainer extends React.PureComponent<Props, State> { | |||
mounted: boolean; | |||
constructor(props: Props) { | |||
@@ -49,12 +49,12 @@ export default class ProjectContainer extends React.PureComponent<Props, State> | |||
componentDidMount() { | |||
this.mounted = true; | |||
this.fetchProject(); | |||
this.fetchComponent(); | |||
} | |||
componentDidUpdate(prevProps: Props) { | |||
if (prevProps.location.query.id !== this.props.location.query.id) { | |||
this.fetchProject(); | |||
this.fetchComponent(); | |||
} | |||
} | |||
@@ -67,7 +67,7 @@ export default class ProjectContainer extends React.PureComponent<Props, State> | |||
qualifier: component.breadcrumbs[component.breadcrumbs.length - 1].qualifier | |||
}); | |||
fetchProject() { | |||
fetchComponent() { | |||
const { branch, id } = this.props.location.query; | |||
this.setState({ loading: true }); | |||
@@ -96,7 +96,7 @@ export default class ProjectContainer extends React.PureComponent<Props, State> | |||
return project ? getBranches(project.key) : Promise.resolve([]); | |||
}; | |||
handleProjectChange = (changes: {}) => { | |||
handleComponentChange = (changes: {}) => { | |||
if (this.mounted) { | |||
this.setState(state => ({ component: { ...state.component, ...changes } })); | |||
} | |||
@@ -123,12 +123,11 @@ export default class ProjectContainer extends React.PureComponent<Props, State> | |||
return <i className="spinner" />; | |||
} | |||
const branch = branches.find(b => (query.branch ? b.name === query.branch : b.isMain)); | |||
if (!component || !branch) { | |||
return <ProjectContainerNotFound />; | |||
if (!component) { | |||
return <ComponentContainerNotFound />; | |||
} | |||
const branch = branches.find(b => (query.branch ? b.name === query.branch : b.isMain)); | |||
const isFile = ['FIL', 'UTS'].includes(component.qualifier); | |||
const configuration = component.configuration || {}; | |||
@@ -147,7 +146,7 @@ export default class ProjectContainer extends React.PureComponent<Props, State> | |||
branches, | |||
component: component, | |||
onBranchesChange: this.handleBranchesChange, | |||
onComponentChange: this.handleProjectChange | |||
onComponentChange: this.handleComponentChange | |||
})} | |||
</div> | |||
); |
@@ -21,7 +21,7 @@ import * as React from 'react'; | |||
import { Link } from 'react-router'; | |||
import { translate } from '../../helpers/l10n'; | |||
export default class ProjectContainerNotFound extends React.PureComponent { | |||
export default class ComponentContainerNotFound extends React.PureComponent { | |||
componentDidMount() { | |||
const html = document.querySelector('html'); | |||
if (html) { |
@@ -21,14 +21,21 @@ jest.mock('../../../api/branches', () => ({ getBranches: jest.fn() })); | |||
jest.mock('../../../api/components', () => ({ getComponentData: jest.fn() })); | |||
jest.mock('../../../api/nav', () => ({ getComponentNavigation: jest.fn() })); | |||
// mock this, because some of its children are using redux store | |||
jest.mock('../nav/component/ComponentNav', () => ({ | |||
default: () => null | |||
})); | |||
import * as React from 'react'; | |||
import { shallow, mount } from 'enzyme'; | |||
import ProjectContainer from '../ProjectContainer'; | |||
import ComponentContainer from '../ComponentContainer'; | |||
import { getBranches } from '../../../api/branches'; | |||
import { getComponentData } from '../../../api/components'; | |||
import { getComponentNavigation } from '../../../api/nav'; | |||
import { doAsync } from '../../../helpers/testUtils'; | |||
const Inner = () => <div />; | |||
beforeEach(() => { | |||
(getBranches as jest.Mock<any>).mockClear(); | |||
(getComponentData as jest.Mock<any>).mockClear(); | |||
@@ -36,14 +43,12 @@ beforeEach(() => { | |||
}); | |||
it('changes component', () => { | |||
const Inner = () => <div />; | |||
const wrapper = shallow( | |||
<ProjectContainer location={{ query: { id: 'foo' } }}> | |||
<ComponentContainer location={{ query: { id: 'foo' } }}> | |||
<Inner /> | |||
</ProjectContainer> | |||
</ComponentContainer> | |||
); | |||
(wrapper.instance() as ProjectContainer).mounted = true; | |||
(wrapper.instance() as ComponentContainer).mounted = true; | |||
wrapper.setState({ | |||
branches: [{ isMain: true }], | |||
component: { qualifier: 'TRK', visibility: 'public' }, | |||
@@ -67,9 +72,9 @@ it("loads branches for module's project", () => { | |||
); | |||
mount( | |||
<ProjectContainer location={{ query: { id: 'moduleKey' } }}> | |||
<div /> | |||
</ProjectContainer> | |||
<ComponentContainer location={{ query: { id: 'moduleKey' } }}> | |||
<Inner /> | |||
</ComponentContainer> | |||
); | |||
return doAsync().then(() => { | |||
@@ -88,28 +93,28 @@ it("doesn't load branches portfolio", () => { | |||
}) | |||
); | |||
mount( | |||
<ProjectContainer location={{ query: { id: 'portfolioKey' } }}> | |||
<div /> | |||
</ProjectContainer> | |||
const wrapper = mount( | |||
<ComponentContainer location={{ query: { id: 'portfolioKey' } }}> | |||
<Inner /> | |||
</ComponentContainer> | |||
); | |||
return doAsync().then(() => { | |||
expect(getBranches).not.toBeCalled(); | |||
expect(getComponentData).toBeCalledWith('portfolioKey', undefined); | |||
expect(getComponentNavigation).toBeCalledWith('portfolioKey'); | |||
expect(wrapper.find(Inner).exists()).toBeTruthy(); | |||
}); | |||
}); | |||
it('updates branches on change', () => { | |||
(getBranches as jest.Mock<any>).mockImplementation(() => Promise.resolve([])); | |||
const Inner = () => <div />; | |||
const wrapper = shallow( | |||
<ProjectContainer location={{ query: { id: 'portfolioKey' } }}> | |||
<ComponentContainer location={{ query: { id: 'portfolioKey' } }}> | |||
<Inner /> | |||
</ProjectContainer> | |||
</ComponentContainer> | |||
); | |||
(wrapper.instance() as ProjectContainer).mounted = true; | |||
(wrapper.instance() as ComponentContainer).mounted = true; | |||
wrapper.setState({ | |||
branches: [{ isMain: true }], | |||
component: { breadcrumbs: [{ key: 'projectKey', name: 'project', qualifier: 'TRK' }] }, |
@@ -17,14 +17,19 @@ | |||
* 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 * as React from 'react'; | |||
import ProjectPageExtension from './ProjectPageExtension'; | |||
import { Component } from '../../types'; | |||
export default function ViewDashboard(props /*: Object */) { | |||
interface Props { | |||
component: Component; | |||
location: { query: { id: string } }; | |||
} | |||
export default function PortfolioDashboard(props: Props) { | |||
return ( | |||
<ProjectPageExtension | |||
location={props.location} | |||
{...props} | |||
params={{ pluginKey: 'governance', extensionKey: 'governance' }} | |||
/> | |||
); |
@@ -32,7 +32,7 @@ import './ComponentNav.css'; | |||
interface Props { | |||
branches: Branch[]; | |||
currentBranch: Branch; | |||
currentBranch?: Branch; | |||
component: Component; | |||
conf: ComponentConfiguration; | |||
location: {}; | |||
@@ -99,13 +99,14 @@ export default class ComponentNav extends React.PureComponent<Props, State> { | |||
breadcrumbs={this.props.component.breadcrumbs} | |||
/> | |||
<ComponentNavBranch | |||
branches={this.props.branches} | |||
currentBranch={this.props.currentBranch} | |||
// to close dropdown on any location change | |||
location={this.props.location} | |||
project={this.props.component} | |||
/> | |||
{this.props.currentBranch && | |||
<ComponentNavBranch | |||
branches={this.props.branches} | |||
currentBranch={this.props.currentBranch} | |||
// to close dropdown on any location change | |||
location={this.props.location} | |||
project={this.props.component} | |||
/>} | |||
<ComponentNavMeta | |||
branch={this.props.currentBranch} |
@@ -46,7 +46,7 @@ const SETTINGS_URLS = [ | |||
]; | |||
interface Props { | |||
branch: Branch; | |||
branch?: Branch; | |||
component: Component; | |||
conf: ComponentConfiguration; | |||
location?: any; | |||
@@ -75,7 +75,7 @@ export default class ComponentNavMenu extends React.PureComponent<Props> { | |||
} | |||
renderDashboardLink() { | |||
if (isShortLivingBranch(this.props.branch)) { | |||
if (this.props.branch && isShortLivingBranch(this.props.branch)) { | |||
return null; | |||
} | |||
@@ -85,7 +85,10 @@ export default class ComponentNavMenu extends React.PureComponent<Props> { | |||
<Link | |||
to={{ | |||
pathname, | |||
query: { branch: getBranchName(this.props.branch), id: this.props.component.key } | |||
query: { | |||
branch: this.props.branch && getBranchName(this.props.branch), | |||
id: this.props.component.key | |||
} | |||
}} | |||
activeClassName="active"> | |||
{translate('overview.page')} | |||
@@ -104,7 +107,10 @@ export default class ComponentNavMenu extends React.PureComponent<Props> { | |||
<Link | |||
to={{ | |||
pathname: '/code', | |||
query: { branch: getBranchName(this.props.branch), id: this.props.component.key } | |||
query: { | |||
branch: this.props.branch && getBranchName(this.props.branch), | |||
id: this.props.component.key | |||
} | |||
}} | |||
activeClassName="active"> | |||
{this.isView() || this.isApplication() | |||
@@ -120,7 +126,7 @@ export default class ComponentNavMenu extends React.PureComponent<Props> { | |||
return null; | |||
} | |||
if (isShortLivingBranch(this.props.branch)) { | |||
if (this.props.branch && isShortLivingBranch(this.props.branch)) { | |||
return null; | |||
} | |||
@@ -129,7 +135,10 @@ export default class ComponentNavMenu extends React.PureComponent<Props> { | |||
<Link | |||
to={{ | |||
pathname: '/project/activity', | |||
query: { branch: getBranchName(this.props.branch), id: this.props.component.key } | |||
query: { | |||
branch: this.props.branch && getBranchName(this.props.branch), | |||
id: this.props.component.key | |||
} | |||
}} | |||
activeClassName="active"> | |||
{translate('project_activity.page')} | |||
@@ -145,7 +154,7 @@ export default class ComponentNavMenu extends React.PureComponent<Props> { | |||
to={{ | |||
pathname: '/project/issues', | |||
query: { | |||
branch: getBranchName(this.props.branch), | |||
branch: this.props.branch && getBranchName(this.props.branch), | |||
id: this.props.component.key, | |||
resolved: 'false' | |||
} | |||
@@ -158,7 +167,7 @@ export default class ComponentNavMenu extends React.PureComponent<Props> { | |||
} | |||
renderComponentMeasuresLink() { | |||
if (isShortLivingBranch(this.props.branch)) { | |||
if (this.props.branch && isShortLivingBranch(this.props.branch)) { | |||
return null; | |||
} | |||
@@ -167,7 +176,10 @@ export default class ComponentNavMenu extends React.PureComponent<Props> { | |||
<Link | |||
to={{ | |||
pathname: '/component_measures', | |||
query: { branch: getBranchName(this.props.branch), id: this.props.component.key } | |||
query: { | |||
branch: this.props.branch && getBranchName(this.props.branch), | |||
id: this.props.component.key | |||
} | |||
}} | |||
activeClassName="active"> | |||
{translate('layout.measures')} | |||
@@ -177,7 +189,7 @@ export default class ComponentNavMenu extends React.PureComponent<Props> { | |||
} | |||
renderAdministration() { | |||
if (isShortLivingBranch(this.props.branch)) { | |||
if (this.props.branch && isShortLivingBranch(this.props.branch)) { | |||
return null; | |||
} | |||
@@ -205,7 +217,7 @@ export default class ComponentNavMenu extends React.PureComponent<Props> { | |||
} | |||
renderAdministrationLinks() { | |||
return isLongLivingBranch(this.props.branch) | |||
return this.props.branch && isLongLivingBranch(this.props.branch) | |||
? [this.renderSettingsLink()] | |||
: [ | |||
this.renderSettingsLink(), | |||
@@ -231,7 +243,10 @@ export default class ComponentNavMenu extends React.PureComponent<Props> { | |||
<Link | |||
to={{ | |||
pathname: '/project/settings', | |||
query: { branch: getBranchName(this.props.branch), id: this.props.component.key } | |||
query: { | |||
branch: this.props.branch && getBranchName(this.props.branch), | |||
id: this.props.component.key | |||
} | |||
}} | |||
activeClassName="active"> | |||
{translate('project_settings.page')} |
@@ -28,7 +28,7 @@ import { translate, translateWithParameters } from '../../../../helpers/l10n'; | |||
import { isShortLivingBranch } from '../../../../helpers/branches'; | |||
interface Props { | |||
branch: Branch; | |||
branch?: Branch; | |||
component: Component; | |||
conf: ComponentConfiguration; | |||
incremental?: boolean; | |||
@@ -91,7 +91,7 @@ export default function ComponentNavMeta(props: Props) { | |||
); | |||
} | |||
if (props.component.analysisDate && props.branch.isMain) { | |||
if (props.component.analysisDate && (!props.branch || props.branch.isMain)) { | |||
metaList.push( | |||
<li key="analysisDate"> | |||
<DateTimeFormatter date={props.component.analysisDate} /> | |||
@@ -99,7 +99,7 @@ export default function ComponentNavMeta(props: Props) { | |||
); | |||
} | |||
if (props.component.version && props.branch.isMain) { | |||
if (props.component.version && (!props.branch || props.branch.isMain)) { | |||
metaList.push( | |||
<li key="version"> | |||
Version {props.component.version} | |||
@@ -115,7 +115,7 @@ export default function ComponentNavMeta(props: Props) { | |||
); | |||
} | |||
if (isShortLivingBranch(props.branch)) { | |||
if (props.branch && isShortLivingBranch(props.branch)) { | |||
metaList.push( | |||
<li className="navbar-context-meta-branch" key="branch-status"> | |||
<BranchStatus branch={props.branch} /> |
@@ -32,7 +32,7 @@ import Landing from '../components/Landing'; | |||
import ProjectAdminContainer from '../components/ProjectAdminContainer'; | |||
import ProjectPageExtension from '../components/extensions/ProjectPageExtension'; | |||
import ProjectAdminPageExtension from '../components/extensions/ProjectAdminPageExtension'; | |||
import ViewDashboard from '../components/extensions/ViewDashboard'; | |||
import PortfolioDashboard from '../components/extensions/PortfolioDashboard'; | |||
import PortfoliosPage from '../components/extensions/PortfoliosPage'; | |||
import AdminContainer from '../components/AdminContainer'; | |||
import GlobalPageExtension from '../components/extensions/GlobalPageExtension'; | |||
@@ -170,7 +170,7 @@ const startReactApp = () => { | |||
<Route | |||
getComponent={() => | |||
import('../components/ProjectContainer').then(i => i.default)}> | |||
import('../components/ComponentContainer').then(i => i.default)}> | |||
<Route path="code" childRoutes={codeRoutes} /> | |||
<Route path="component_measures" childRoutes={componentMeasuresRoutes} /> | |||
<Route path="custom_measures" childRoutes={customMeasuresRoutes} /> | |||
@@ -194,7 +194,7 @@ const startReactApp = () => { | |||
{projectAdminRoutes} | |||
</Route> | |||
<Route path="project_roles" childRoutes={projectPermissionsRoutes} /> | |||
<Route path="portfolio" component={ViewDashboard} /> | |||
<Route path="portfolio" component={PortfolioDashboard} /> | |||
</Route> | |||
<Route component={AdminContainer}> |
@@ -39,7 +39,7 @@ import '../code.css'; | |||
import { Component, Branch } from '../../../app/types'; | |||
interface Props { | |||
branch: Branch; | |||
branch?: Branch; | |||
component: Component; | |||
location: { query: { [x: string]: string } }; | |||
} | |||
@@ -91,7 +91,7 @@ export default class App extends React.PureComponent<Props, State> { | |||
this.setState({ loading: true }); | |||
const isPortfolio = ['VW', 'SVW'].includes(component.qualifier); | |||
retrieveComponentChildren(component.key, isPortfolio, getBranchName(branch)) | |||
retrieveComponentChildren(component.key, isPortfolio, branch && getBranchName(branch)) | |||
.then(() => { | |||
addComponent(component); | |||
this.handleUpdate(); | |||
@@ -108,7 +108,11 @@ export default class App extends React.PureComponent<Props, State> { | |||
this.setState({ loading: true }); | |||
const isPortfolio = ['VW', 'SVW'].includes(this.props.component.qualifier); | |||
retrieveComponent(componentKey, isPortfolio, getBranchName(this.props.branch)) | |||
retrieveComponent( | |||
componentKey, | |||
isPortfolio, | |||
this.props.branch && getBranchName(this.props.branch) | |||
) | |||
.then(r => { | |||
if (this.mounted) { | |||
if (['FIL', 'UTS'].includes(r.component.qualifier)) { | |||
@@ -154,7 +158,12 @@ export default class App extends React.PureComponent<Props, State> { | |||
return; | |||
} | |||
const isPortfolio = ['VW', 'SVW'].includes(this.props.component.qualifier); | |||
loadMoreChildren(baseComponent.key, page + 1, isPortfolio, getBranchName(this.props.branch)) | |||
loadMoreChildren( | |||
baseComponent.key, | |||
page + 1, | |||
isPortfolio, | |||
this.props.branch && getBranchName(this.props.branch) | |||
) | |||
.then(r => { | |||
if (this.mounted) { | |||
this.setState({ | |||
@@ -189,7 +198,7 @@ export default class App extends React.PureComponent<Props, State> { | |||
total, | |||
sourceViewer | |||
} = this.state; | |||
const branchName = getBranchName(branch); | |||
const branchName = branch && getBranchName(branch); | |||
const shouldShowBreadcrumbs = breadcrumbs.length > 1; | |||
@@ -34,7 +34,7 @@ import { translate } from '../../../helpers/l10n'; | |||
import '../style.css'; | |||
/*:: type Props = {| | |||
branch: {}, | |||
branch?: {}, | |||
component: Component, | |||
currentUser: { isLoggedIn: boolean }, | |||
location: { pathname: string, query: RawQuery }, | |||
@@ -106,7 +106,7 @@ export default class App extends React.PureComponent { | |||
const filteredKeys = metricsKey.filter( | |||
key => !metrics[key].hidden && !['DATA', 'DISTRIB'].includes(metrics[key].type) | |||
); | |||
fetchMeasures(component.key, filteredKeys, getBranchName(branch)).then( | |||
fetchMeasures(component.key, filteredKeys, branch && getBranchName(branch)).then( | |||
({ measures, leakPeriod }) => { | |||
if (this.mounted) { | |||
this.setState({ | |||
@@ -127,7 +127,11 @@ export default class App extends React.PureComponent { | |||
}); | |||
this.props.router.push({ | |||
pathname: this.props.location.pathname, | |||
query: { ...query, branch: getBranchName(this.props.branch), id: this.props.component.key } | |||
query: { | |||
...query, | |||
branch: this.props.branch && getBranchName(this.props.branch), | |||
id: this.props.component.key | |||
} | |||
}); | |||
}; | |||
@@ -160,7 +164,7 @@ export default class App extends React.PureComponent { | |||
{metric != null && | |||
<MeasureContentContainer | |||
branch={getBranchName(branch)} | |||
branch={branch && getBranchName(branch)} | |||
className="layout-page-main" | |||
currentUser={this.props.currentUser} | |||
rootComponent={component} | |||
@@ -176,7 +180,7 @@ export default class App extends React.PureComponent { | |||
{metric == null && | |||
hasBubbleChart(query.metric) && | |||
<MeasureOverviewContainer | |||
branch={getBranchName(branch)} | |||
branch={branch && getBranchName(branch)} | |||
className="layout-page-main" | |||
rootComponent={component} | |||
currentUser={this.props.currentUser} |
@@ -28,7 +28,7 @@ import SourceViewer from '../../../components/SourceViewer/SourceViewer'; | |||
/*:: | |||
type Props = { | |||
branch: { name: string }, | |||
branch?: { name: string }, | |||
component: { | |||
analysisDate?: string, | |||
id: string, | |||
@@ -75,7 +75,7 @@ export default class App extends React.PureComponent { | |||
if (['FIL', 'UTS'].includes(component.qualifier)) { | |||
return ( | |||
<div className="page page-limited"> | |||
<SourceViewer branch={getBranchName(branch)} component={component.key} /> | |||
<SourceViewer branch={branch && getBranchName(branch)} component={component.key} /> | |||
</div> | |||
); | |||
} |
@@ -42,7 +42,7 @@ import '../styles.css'; | |||
/*:: | |||
type Props = { | |||
branch: { name: string }, | |||
branch?: { name: string }, | |||
component: Component, | |||
onComponentChange: {} => void | |||
}; | |||
@@ -98,7 +98,7 @@ export default class OverviewApp extends React.PureComponent { | |||
return getMeasuresAndMeta(component.key, METRICS, { | |||
additionalFields: 'metrics,periods', | |||
branch: getBranchName(branch) | |||
branch: branch && getBranchName(branch) | |||
}).then( | |||
r => { | |||
if (this.mounted) { | |||
@@ -128,7 +128,7 @@ export default class OverviewApp extends React.PureComponent { | |||
const metrics = uniq(HISTORY_METRICS_LIST.concat(graphMetrics)); | |||
return getAllTimeMachineData(component.key, metrics, { | |||
branch: getBranchName(branch) | |||
branch: branch && getBranchName(branch) | |||
}).then(r => { | |||
if (this.mounted) { | |||
const history /*: History */ = {}; | |||
@@ -166,7 +166,7 @@ export default class OverviewApp extends React.PureComponent { | |||
const leakPeriod = | |||
component.qualifier === 'APP' ? this.getApplicationLeakPeriod() : getLeakPeriod(periods); | |||
const branchName = getBranchName(branch); | |||
const branchName = branch && getBranchName(branch); | |||
const domainProps = { | |||
branch: branchName, | |||
component, |
@@ -43,7 +43,7 @@ import { | |||
/*:: | |||
type Props = { | |||
branch: {}, | |||
branch?: {}, | |||
location: { pathname: string, query: RawQuery }, | |||
component: { | |||
configuration?: { showHistory: boolean }, | |||
@@ -95,7 +95,10 @@ export default class ProjectActivityAppContainer extends React.PureComponent { | |||
} | |||
this.context.router.replace({ | |||
pathname: props.location.pathname, | |||
query: { ...serializeUrlQuery(newQuery), branch: getBranchName(props.branch) } | |||
query: { | |||
...serializeUrlQuery(newQuery), | |||
branch: props.branch && getBranchName(props.branch) | |||
} | |||
}); | |||
} | |||
} | |||
@@ -169,7 +172,12 @@ export default class ProjectActivityAppContainer extends React.PureComponent { | |||
[string]: string | |||
} */ | |||
) => { | |||
const parameters = { project, p, ps, branch: getBranchName(this.props.branch) }; | |||
const parameters = { | |||
project, | |||
p, | |||
ps, | |||
branch: this.props.branch && getBranchName(this.props.branch) | |||
}; | |||
return api | |||
.getProjectActivity({ ...parameters, ...additional }) | |||
.then(({ analyses, paging }) => ({ | |||
@@ -183,7 +191,7 @@ export default class ProjectActivityAppContainer extends React.PureComponent { | |||
return Promise.resolve([]); | |||
} | |||
return getAllTimeMachineData(this.props.component.key, metrics, { | |||
branch: getBranchName(this.props.branch) | |||
branch: this.props.branch && getBranchName(this.props.branch) | |||
}).then( | |||
({ measures }) => | |||
measures.map(measure => ({ | |||
@@ -285,7 +293,7 @@ export default class ProjectActivityAppContainer extends React.PureComponent { | |||
pathname: this.props.location.pathname, | |||
query: { | |||
...query, | |||
branch: getBranchName(this.props.branch), | |||
branch: this.props.branch && getBranchName(this.props.branch), | |||
id: this.props.component.key | |||
} | |||
}); |
@@ -24,7 +24,7 @@ import Definition from './Definition'; | |||
export default class DefinitionsList extends React.PureComponent { | |||
static propTypes = { | |||
branch: PropTypes.object, | |||
branch: PropTypes.string, | |||
component: PropTypes.object, | |||
settings: PropTypes.array.isRequired | |||
}; |