]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-9166 allow to change default project visibility on-premise (#2022)
authorStas Vilchik <stas-vilchik@users.noreply.github.com>
Fri, 5 May 2017 12:11:22 +0000 (14:11 +0200)
committerGitHub <noreply@github.com>
Fri, 5 May 2017 12:11:22 +0000 (14:11 +0200)
server/sonar-web/src/main/js/apps/permissions/project/views/ApplyTemplateView.js
server/sonar-web/src/main/js/apps/projects-admin/AppContainer.js
server/sonar-web/src/main/js/apps/projects-admin/header.js
server/sonar-web/src/main/js/apps/projects-admin/main.js
server/sonar-web/src/main/js/apps/projects-admin/projects.js

index 07e5da1482df314e78d85690247ed105fa2e3b11..a7c8c972d0b10c7bd35e08a22ff21d0384e9b0d1 100644 (file)
@@ -30,10 +30,7 @@ export default ModalForm.extend({
   },
 
   loadPermissionTemplates() {
-    const request = this.options.organization
-      ? getPermissionTemplates(this.options.organization.key)
-      : getPermissionTemplates();
-    return request.then(r => {
+    return getPermissionTemplates(this.options.organization.key).then(r => {
       this.permissionTemplates = r.permissionTemplates;
       this.render();
     });
@@ -53,12 +50,10 @@ export default ModalForm.extend({
     this.disableForm();
 
     const data = {
+      organization: this.options.organization.key,
       projectKey: this.options.project.key,
       templateId: permissionTemplate
     };
-    if (this.options.organization) {
-      data.organization = this.options.organization.key;
-    }
     applyTemplateToProject(data)
       .then(() => {
         this.trigger('done');
index 98bbe16a4f84570c62fe8147bba93199b74e57a2..69f890b5caa297ca8ae3b76181910076952e1d52 100644 (file)
@@ -21,34 +21,53 @@ import React from 'react';
 import { connect } from 'react-redux';
 import Main from './main';
 import { onFail } from '../../store/rootActions';
-import { getCurrentUser, getAppState } from '../../store/rootReducer';
-import { getRootQualifiers } from '../../store/appState/duck';
+import { getAppState, getOrganizationByKey } from '../../store/rootReducer';
 import { receiveOrganizations } from '../../store/organizations/duck';
 import { changeProjectVisibility } from '../../api/organizations';
+import { fetchOrganization } from '../../apps/organizations/actions';
 
-function AppContainer(props) {
-  const hasProvisionPermission = props.organization
-    ? props.organization.canProvisionProjects
-    : props.user.permissions.global.indexOf('provisioning') !== -1;
+class AppContainer extends React.PureComponent {
+  componentDidMount() {
+    // if there is no organization, that means we are in the global scope
+    // let's fetch defails for the default organization in this case
+    if (!this.props.organization || !this.props.organization.projectVisibility) {
+      this.props.fetchOrganization(this.props.appState.defaultOrganization);
+    }
+  }
 
-  const topLevelQualifiers = props.organization && !props.organization.isDefault
-    ? ['TRK']
-    : props.rootQualifiers;
+  componentWillUnmount() {
+    this.mounted = false;
+  }
 
-  return (
-    <Main
-      hasProvisionPermission={hasProvisionPermission}
-      topLevelQualifiers={topLevelQualifiers}
-      onVisibilityChange={props.onVisibilityChange}
-      onRequestFail={props.onRequestFail}
-      organization={props.organization}
-    />
-  );
+  handleVisibilityChange = visibility => {
+    this.props.onVisibilityChange(this.props.organization, visibility);
+  };
+
+  render() {
+    const { organization } = this.props;
+
+    if (!organization) {
+      return null;
+    }
+
+    const topLevelQualifiers = organization.isDefault ? this.props.appState.qualifiers : ['TRK'];
+
+    return (
+      <Main
+        hasProvisionPermission={organization.canProvisionProjects}
+        topLevelQualifiers={topLevelQualifiers}
+        onVisibilityChange={this.handleVisibilityChange}
+        onRequestFail={this.props.onRequestFail}
+        organization={organization}
+      />
+    );
+  }
 }
 
-const mapStateToProps = state => ({
-  rootQualifiers: getRootQualifiers(getAppState(state)),
-  user: getCurrentUser(state)
+const mapStateToProps = (state, ownProps) => ({
+  appState: getAppState(state),
+  organization: ownProps.organization ||
+    getOrganizationByKey(state, getAppState(state).defaultOrganization)
 });
 
 const onVisibilityChange = (organization, visibility) => dispatch => {
@@ -60,8 +79,10 @@ const onVisibilityChange = (organization, visibility) => dispatch => {
   });
 };
 
-const mapDispatchToProps = (dispatch, ownProps) => ({
-  onVisibilityChange: visibility => dispatch(onVisibilityChange(ownProps.organization, visibility)),
+const mapDispatchToProps = dispatch => ({
+  fetchOrganization: key => dispatch(fetchOrganization(key)),
+  onVisibilityChange: (organization, visibility) =>
+    dispatch(onVisibilityChange(organization, visibility)),
   onRequestFail: error => onFail(dispatch)(error)
 });
 
index a6171607dc8625f01e251111e9289588500d6fbe..f0b23d0ef61d85a91e3d8ef989f61289733a4cdd 100644 (file)
@@ -27,7 +27,7 @@ type Props = {|
   hasProvisionPermission: boolean,
   onProjectCreate: () => void,
   onVisibilityChange: string => void,
-  organization?: Organization
+  organization: Organization
 |};
 
 type State = {
@@ -59,19 +59,18 @@ export default class Header extends React.PureComponent {
       <header className="page-header">
         <h1 className="page-title">{translate('projects_management')}</h1>
         <div className="page-actions">
-          {organization != null &&
-            <span className="big-spacer-right">
-              {translate('organization.default_visibility_of_new_projects')}
-              {' '}
-              <strong>
-                {translate('visibility', organization.projectVisibility)}
-              </strong>
-              <a
-                className="spacer-left icon-edit"
-                href="#"
-                onClick={this.handleChangeVisibilityClick}
-              />
-            </span>}
+          <span className="big-spacer-right">
+            {translate('organization.default_visibility_of_new_projects')}
+            {' '}
+            <strong>
+              {translate('visibility', organization.projectVisibility)}
+            </strong>
+            <a
+              className="spacer-left icon-edit"
+              href="#"
+              onClick={this.handleChangeVisibilityClick}
+            />
+          </span>
           {this.props.hasProvisionPermission &&
             <button id="create-project" onClick={this.handleCreateProjectClick}>
               {translate('qualifiers.create.TRK')}
@@ -82,7 +81,6 @@ export default class Header extends React.PureComponent {
         </p>
 
         {this.state.visibilityForm &&
-          organization != null &&
           <ChangeVisibilityForm
             onClose={this.closeVisiblityForm}
             onConfirm={this.props.onVisibilityChange}
index 3d6a154acf881dc51016e0a281036303666d9233..cb1c99b30f3c00f5837357b7304d75aa7b8c057c 100644 (file)
@@ -33,7 +33,7 @@ type Props = {|
   hasProvisionPermission: boolean,
   onVisibilityChange: string => void,
   onRequestFail: Object => void,
-  organization?: Organization
+  organization: Organization
 |};
 
 type State = {
@@ -73,16 +73,16 @@ export default class Main extends React.PureComponent {
   }
 
   getFilters = () => {
-    const filters: { [string]: string | number } = { ps: PAGE_SIZE };
+    const filters: { [string]: string | number } = {
+      organization: this.props.organization.key,
+      ps: PAGE_SIZE
+    };
     if (this.state.page !== 1) {
       filters.p = this.state.page;
     }
     if (this.state.query) {
       filters.q = this.state.query;
     }
-    if (this.props.organization) {
-      filters.organization = this.props.organization.key;
-    }
     return filters;
   };
 
@@ -211,10 +211,10 @@ export default class Main extends React.PureComponent {
   deleteProjects = () => {
     this.setState({ ready: false });
     const projects = this.state.selection.join(',');
-    const data = { projects };
-    if (this.props.organization) {
-      Object.assign(data, { organization: this.props.organization.key });
-    }
+    const data = {
+      organization: this.props.organization.key,
+      projects
+    };
     deleteComponents(data).then(() => {
       this.setState({ page: 1, selection: [] }, this.requestProjects);
     });
index bc1f94eda6382a987d1af5d52d0331c219862f08..cbf2aab4a72d941f83783b90db77234a80f94acd 100644 (file)
@@ -31,7 +31,7 @@ export default class Projects extends React.PureComponent {
   static propTypes = {
     projects: React.PropTypes.array.isRequired,
     selection: React.PropTypes.array.isRequired,
-    organization: React.PropTypes.object
+    organization: React.PropTypes.object.isRequired
   };
 
   componentWillMount() {