diff options
Diffstat (limited to 'server/sonar-web/src/main/js/app/components/ComponentContainer.tsx')
-rw-r--r-- | server/sonar-web/src/main/js/app/components/ComponentContainer.tsx | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/server/sonar-web/src/main/js/app/components/ComponentContainer.tsx b/server/sonar-web/src/main/js/app/components/ComponentContainer.tsx new file mode 100644 index 00000000000..27ccf26396e --- /dev/null +++ b/server/sonar-web/src/main/js/app/components/ComponentContainer.tsx @@ -0,0 +1,154 @@ +/* + * 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 * as React from 'react'; +import ComponentContainerNotFound from './ComponentContainerNotFound'; +import ComponentNav from './nav/component/ComponentNav'; +import { Branch, Component } from '../types'; +import handleRequiredAuthorization from '../utils/handleRequiredAuthorization'; +import { getBranches } from '../../api/branches'; +import { getComponentData } from '../../api/components'; +import { getComponentNavigation } from '../../api/nav'; + +interface Props { + children: any; + location: { + query: { branch?: string; id: string }; + }; +} + +interface State { + branches: Branch[]; + loading: boolean; + component: Component | null; +} + +export default class ComponentContainer extends React.PureComponent<Props, State> { + mounted: boolean; + + constructor(props: Props) { + super(props); + this.state = { branches: [], loading: true, component: null }; + } + + componentDidMount() { + this.mounted = true; + this.fetchComponent(); + } + + componentDidUpdate(prevProps: Props) { + if (prevProps.location.query.id !== this.props.location.query.id) { + this.fetchComponent(); + } + } + + componentWillUnmount() { + this.mounted = false; + } + + addQualifier = (component: Component) => ({ + ...component, + qualifier: component.breadcrumbs[component.breadcrumbs.length - 1].qualifier + }); + + fetchComponent() { + const { branch, id } = this.props.location.query; + this.setState({ loading: true }); + + const onError = (error: any) => { + if (this.mounted) { + if (error.response && error.response.status === 403) { + handleRequiredAuthorization(); + } else { + this.setState({ loading: false }); + } + } + }; + + Promise.all([getComponentNavigation(id), getComponentData(id, branch)]).then(([nav, data]) => { + const component = this.addQualifier({ ...nav, ...data }); + this.fetchBranches(component).then(branches => { + if (this.mounted) { + this.setState({ loading: false, branches, component }); + } + }, onError); + }, onError); + } + + fetchBranches = (component: Component) => { + const project = component.breadcrumbs.find((c: Component) => c.qualifier === 'TRK'); + return project ? getBranches(project.key) : Promise.resolve([]); + }; + + handleComponentChange = (changes: {}) => { + if (this.mounted) { + this.setState(state => ({ component: { ...state.component, ...changes } })); + } + }; + + handleBranchesChange = () => { + if (this.mounted && this.state.component) { + this.fetchBranches(this.state.component).then( + branches => { + if (this.mounted) { + this.setState({ branches }); + } + }, + () => {} + ); + } + }; + + render() { + const { query } = this.props.location; + const { branches, component, loading } = this.state; + + if (loading) { + return <i className="spinner" />; + } + + 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 || {}; + + return ( + <div> + {!isFile && + <ComponentNav + branches={branches} + currentBranch={branch} + component={component} + conf={configuration} + location={this.props.location} + />} + {React.cloneElement(this.props.children, { + branch, + branches, + component: component, + onBranchesChange: this.handleBranchesChange, + onComponentChange: this.handleComponentChange + })} + </div> + ); + } +} |