From abced7a7e962a91b53b0d50465a01d6100d87a57 Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Wed, 16 Dec 2020 15:38:48 +0100 Subject: [PATCH] SONAR-13999 Use global default project visibility --- .../src/main/js/api/organizations.ts | 15 --- .../sonar-web/src/main/js/api/permissions.ts | 3 +- .../main/js/apps/projectsManagement/App.tsx | 71 +++++++++---- .../apps/projectsManagement/AppContainer.tsx | 100 ------------------ .../ChangeDefaultVisibilityForm.tsx | 18 ++-- .../projectsManagement/CreateProjectForm.tsx | 10 +- .../js/apps/projectsManagement/Header.tsx | 38 +++---- .../projectsManagement/__tests__/App-test.tsx | 48 ++++++--- .../ChangeDefaultVisibilityForm-test.tsx | 16 +-- .../__tests__/CreateProjectForm-test.tsx | 9 +- .../__tests__/Header-test.tsx | 21 ++-- .../ChangeDefaultVisibilityForm-test.tsx.snap | 79 -------------- .../CreateProjectForm-test.tsx.snap | 3 + .../__snapshots__/Header-test.tsx.snap | 54 ++++++++-- .../main/js/apps/projectsManagement/routes.ts | 2 +- .../src/main/js/store/rootActions.ts | 24 ++--- .../sonar-web/src/main/js/types/settings.ts | 3 +- 17 files changed, 187 insertions(+), 327 deletions(-) delete mode 100644 server/sonar-web/src/main/js/apps/projectsManagement/AppContainer.tsx diff --git a/server/sonar-web/src/main/js/api/organizations.ts b/server/sonar-web/src/main/js/api/organizations.ts index e5c2a1c0773..dd38f41fa6c 100644 --- a/server/sonar-web/src/main/js/api/organizations.ts +++ b/server/sonar-web/src/main/js/api/organizations.ts @@ -36,18 +36,3 @@ export function getOrganization(key: string): Promise { - return getJSON('/api/navigation/organization', { organization: key }).then( - r => r.organization, - throwGlobalError - ); -} diff --git a/server/sonar-web/src/main/js/api/permissions.ts b/server/sonar-web/src/main/js/api/permissions.ts index d87932fe7cd..a5b120e0362 100644 --- a/server/sonar-web/src/main/js/api/permissions.ts +++ b/server/sonar-web/src/main/js/api/permissions.ts @@ -216,10 +216,9 @@ export function changeProjectVisibility( } export function changeProjectDefaultVisibility( - organization: string, projectVisibility: T.Visibility ): Promise { - return post('/api/projects/update_default_visibility', { organization, projectVisibility }).catch( + return post('/api/projects/update_default_visibility', { projectVisibility }).catch( throwGlobalError ); } diff --git a/server/sonar-web/src/main/js/apps/projectsManagement/App.tsx b/server/sonar-web/src/main/js/apps/projectsManagement/App.tsx index 0263a094a3b..a234b778029 100644 --- a/server/sonar-web/src/main/js/apps/projectsManagement/App.tsx +++ b/server/sonar-web/src/main/js/apps/projectsManagement/App.tsx @@ -20,27 +20,31 @@ import { debounce, uniq, without } from 'lodash'; import * as React from 'react'; import { Helmet } from 'react-helmet-async'; +import { connect } from 'react-redux'; import ListFooter from 'sonar-ui-common/components/controls/ListFooter'; import { toShortNotSoISOString } from 'sonar-ui-common/helpers/dates'; import { translate } from 'sonar-ui-common/helpers/l10n'; import { getComponents, Project } from '../../api/components'; +import { changeProjectDefaultVisibility } from '../../api/permissions'; +import { getValues } from '../../api/settings'; import Suggestions from '../../app/components/embed-docs-modal/Suggestions'; +import { hasGlobalPermission } from '../../helpers/users'; +import { getAppState, getCurrentUser, Store } from '../../store/rootReducer'; +import { SettingsKey } from '../../types/settings'; import CreateProjectForm from './CreateProjectForm'; import Header from './Header'; import Projects from './Projects'; import Search from './Search'; export interface Props { - currentUser: Pick; - hasProvisionPermission?: boolean; - onVisibilityChange: (visibility: T.Visibility) => void; - organization: T.Organization; - topLevelQualifiers: string[]; + currentUser: T.LoggedInUser; + appState: Pick; } interface State { analyzedBefore?: Date; createProjectForm: boolean; + defaultProjectVisibility?: T.Visibility; page: number; projects: Project[]; provisioned: boolean; @@ -54,7 +58,7 @@ interface State { const PAGE_SIZE = 50; -export default class App extends React.PureComponent { +export class App extends React.PureComponent { mounted = false; constructor(props: Props) { @@ -76,12 +80,29 @@ export default class App extends React.PureComponent { componentDidMount() { this.mounted = true; this.requestProjects(); + this.fetchDefaultProjectVisibility(); } componentWillUnmount() { this.mounted = false; } + fetchDefaultProjectVisibility = async () => { + const results = await getValues({ keys: SettingsKey.DefaultProjectVisibility }); + + if (this.mounted && results.length > 0 && results[0].value) { + this.setState({ defaultProjectVisibility: results[0].value as T.Visibility }); + } + }; + + handleDefaultProjectVisibilityChange = async (visibility: T.Visibility) => { + await changeProjectDefaultVisibility(visibility); + + if (this.mounted) { + this.setState({ defaultProjectVisibility: visibility }); + } + }; + requestProjects = () => { const { analyzedBefore } = this.state; const parameters = { @@ -93,18 +114,15 @@ export default class App extends React.PureComponent { qualifiers: this.state.qualifiers, visibility: this.state.visibility }; - getComponents(parameters).then( - r => { - if (this.mounted) { - let projects: Project[] = r.components; - if (this.state.page > 1) { - projects = [...this.state.projects, ...projects]; - } - this.setState({ ready: true, projects, selection: [], total: r.paging.total }); + return getComponents(parameters).then(r => { + if (this.mounted) { + let projects: Project[] = r.components; + if (this.state.page > 1) { + projects = [...this.state.projects, ...projects]; } - }, - () => {} - ); + this.setState({ ready: true, projects, selection: [], total: r.paging.total }); + } + }); }; loadMore = () => { @@ -178,16 +196,18 @@ export default class App extends React.PureComponent { }; render() { + const { appState, currentUser } = this.props; + const { defaultProjectVisibility } = this.state; return (
{ query={this.state.query} ready={this.state.ready} selection={this.state.selection} - topLevelQualifiers={this.props.topLevelQualifiers} + topLevelQualifiers={appState.qualifiers} total={this.state.total} visibility={this.state.visibility} /> @@ -229,12 +249,19 @@ export default class App extends React.PureComponent { {this.state.createProjectForm && ( )}
); } } + +const mapStateToProps = (state: Store) => ({ + appState: getAppState(state), + currentUser: getCurrentUser(state) as T.LoggedInUser +}); + +export default connect(mapStateToProps)(App); diff --git a/server/sonar-web/src/main/js/apps/projectsManagement/AppContainer.tsx b/server/sonar-web/src/main/js/apps/projectsManagement/AppContainer.tsx deleted file mode 100644 index 593b7b70407..00000000000 --- a/server/sonar-web/src/main/js/apps/projectsManagement/AppContainer.tsx +++ /dev/null @@ -1,100 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2020 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 { connect } from 'react-redux'; -import { changeProjectDefaultVisibility } from '../../api/permissions'; -import { receiveOrganizations } from '../../store/organizations'; -import { fetchOrganization } from '../../store/rootActions'; -import { getAppState, getCurrentUser, getOrganizationByKey, Store } from '../../store/rootReducer'; -import App from './App'; - -interface StateProps { - appState: { defaultOrganization: string; qualifiers: string[] }; - currentUser: T.LoggedInUser; - organization?: T.Organization; -} - -interface DispatchProps { - fetchOrganization: (organization: string) => void; - onVisibilityChange: (organization: T.Organization, visibility: T.Visibility) => void; -} - -interface OwnProps { - onRequestFail: (error: any) => void; - organization: T.Organization; -} - -class AppContainer extends React.PureComponent { - componentDidMount() { - this.props.fetchOrganization(this.props.appState.defaultOrganization); - } - - handleVisibilityChange = (visibility: T.Visibility) => { - if (this.props.organization) { - 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']; - const { actions = {} } = organization; - - return ( - - ); - } -} - -const mapStateToProps = (state: Store, ownProps: OwnProps) => ({ - appState: getAppState(state), - currentUser: getCurrentUser(state) as T.LoggedInUser, - organization: - ownProps.organization || getOrganizationByKey(state, getAppState(state).defaultOrganization) -}); - -const onVisibilityChange = (organization: T.Organization, visibility: T.Visibility) => ( - dispatch: Function -) => { - const currentVisibility = organization.projectVisibility; - dispatch(receiveOrganizations([{ ...organization, projectVisibility: visibility }])); - changeProjectDefaultVisibility(organization.key, visibility).catch(() => { - dispatch(receiveOrganizations([{ ...organization, projectVisibility: currentVisibility }])); - }); -}; - -const mapDispatchToProps = (dispatch: Function) => ({ - fetchOrganization: (key: string) => dispatch(fetchOrganization(key)), - onVisibilityChange: (organization: T.Organization, visibility: T.Visibility) => - dispatch(onVisibilityChange(organization, visibility)) -}); - -export default connect(mapStateToProps, mapDispatchToProps)(AppContainer); diff --git a/server/sonar-web/src/main/js/apps/projectsManagement/ChangeDefaultVisibilityForm.tsx b/server/sonar-web/src/main/js/apps/projectsManagement/ChangeDefaultVisibilityForm.tsx index 8a037674227..b9545f8f0a7 100644 --- a/server/sonar-web/src/main/js/apps/projectsManagement/ChangeDefaultVisibilityForm.tsx +++ b/server/sonar-web/src/main/js/apps/projectsManagement/ChangeDefaultVisibilityForm.tsx @@ -25,9 +25,9 @@ import { Alert } from 'sonar-ui-common/components/ui/Alert'; import { translate } from 'sonar-ui-common/helpers/l10n'; export interface Props { + defaultVisibility: T.Visibility; onClose: () => void; onConfirm: (visiblity: T.Visibility) => void; - organization: Pick; } interface State { @@ -37,7 +37,7 @@ interface State { export default class ChangeDefaultVisibilityForm extends React.PureComponent { constructor(props: Props) { super(props); - this.state = { visibility: props.organization.projectVisibility as T.Visibility }; + this.state = { visibility: props.defaultVisibility }; } handleConfirmClick = () => { @@ -50,7 +50,6 @@ export default class ChangeDefaultVisibilityForm extends React.PureComponent
@@ -63,10 +62,7 @@ export default class ChangeDefaultVisibilityForm extends React.PureComponent + onCheck={this.handleVisibilityChange}>
{translate('visibility', visibility)}

@@ -77,11 +73,9 @@ export default class ChangeDefaultVisibilityForm extends React.PureComponent ))} - {organization.canUpdateProjectsVisibilityToPrivate && ( - - {translate('organization.change_visibility_form.warning')} - - )} + + {translate('organization.change_visibility_form.warning')} +

diff --git a/server/sonar-web/src/main/js/apps/projectsManagement/CreateProjectForm.tsx b/server/sonar-web/src/main/js/apps/projectsManagement/CreateProjectForm.tsx index 914e1d96a66..e5bf0c2e732 100644 --- a/server/sonar-web/src/main/js/apps/projectsManagement/CreateProjectForm.tsx +++ b/server/sonar-web/src/main/js/apps/projectsManagement/CreateProjectForm.tsx @@ -29,9 +29,9 @@ import VisibilitySelector from '../../components/common/VisibilitySelector'; import { getProjectUrl } from '../../helpers/urls'; interface Props { + defaultProjectVisibility?: T.Visibility; onClose: () => void; onProjectCreated: () => void; - organization: Pick; } interface State { @@ -54,7 +54,7 @@ export default class CreateProjectForm extends React.PureComponent key: '', loading: false, name: '', - visibility: props.organization.projectVisibility + visibility: props.defaultProjectVisibility }; } @@ -110,9 +110,7 @@ export default class CreateProjectForm extends React.PureComponent }; render() { - const { - organization: { canUpdateProjectsVisibilityToPrivate } - } = this.props; + const { defaultProjectVisibility } = this.props; const { createdProject } = this.state; return ( @@ -189,7 +187,7 @@ export default class CreateProjectForm extends React.PureComponent
void; - onVisibilityChange: (visibility: T.Visibility) => void; - organization: Pick; + onChangeDefaultProjectVisibility: (visibility: T.Visibility) => void; } interface State { @@ -45,26 +45,28 @@ export default class Header extends React.PureComponent { }; render() { - const { organization } = this.props; + const { defaultProjectVisibility, hasProvisionPermission } = this.props; + const { visibilityForm } = this.state; return (

{translate('projects_management')}

- {organization.projectVisibility && ( - - - {translate('organization.default_visibility_of_new_projects')}{' '} - {translate('visibility', organization.projectVisibility)} - - + + + {translate('organization.default_visibility_of_new_projects')}{' '} + + {defaultProjectVisibility ? translate('visibility', defaultProjectVisibility) : '—'} + - )} - {this.props.hasProvisionPermission && ( + + + + {hasProvisionPermission && ( @@ -73,11 +75,11 @@ export default class Header extends React.PureComponent {

{translate('projects_management.page.description')}

- {this.state.visibilityForm && ( + {visibilityForm && ( )}
diff --git a/server/sonar-web/src/main/js/apps/projectsManagement/__tests__/App-test.tsx b/server/sonar-web/src/main/js/apps/projectsManagement/__tests__/App-test.tsx index 2bf5d2725ae..15c7c370d84 100644 --- a/server/sonar-web/src/main/js/apps/projectsManagement/__tests__/App-test.tsx +++ b/server/sonar-web/src/main/js/apps/projectsManagement/__tests__/App-test.tsx @@ -19,8 +19,12 @@ */ import { shallow } from 'enzyme'; import * as React from 'react'; +import { waitAndUpdate } from 'sonar-ui-common/helpers/testUtils'; import { getComponents } from '../../../api/components'; -import App, { Props } from '../App'; +import { changeProjectDefaultVisibility } from '../../../api/permissions'; +import { getValues } from '../../../api/settings'; +import { mockAppState, mockLoggedInUser } from '../../../helpers/testMocks'; +import { App, Props } from '../App'; import Search from '../Search'; jest.mock('lodash', () => { @@ -33,7 +37,13 @@ jest.mock('../../../api/components', () => ({ getComponents: jest.fn().mockResolvedValue({ paging: { total: 0 }, components: [] }) })); -const organization: T.Organization = { key: 'org', name: 'org', projectVisibility: 'public' }; +jest.mock('../../../api/permissions', () => ({ + changeProjectDefaultVisibility: jest.fn().mockResolvedValue({}) +})); + +jest.mock('../../../api/settings', () => ({ + getValues: jest.fn().mockResolvedValue([{ value: 'public' }]) +})); const defaultSearchParameters = { p: undefined, @@ -45,9 +55,12 @@ beforeEach(() => { jest.clearAllMocks(); }); -it('fetches all projects on mount', () => { - shallowRender(); +it('fetches all projects on mount', async () => { + const wrapper = shallowRender(); + await waitAndUpdate(wrapper); expect(getComponents).lastCalledWith({ ...defaultSearchParameters, qualifiers: 'TRK' }); + expect(getValues).toBeCalled(); + expect(wrapper.state().defaultProjectVisibility).toBe('public'); }); it('selects provisioned', () => { @@ -86,6 +99,19 @@ it('should handle date filtering', () => { }); }); +it('should handle default project visibility change', async () => { + const wrapper = shallowRender(); + + await waitAndUpdate(wrapper); + + expect(wrapper.state().defaultProjectVisibility).toBe('public'); + wrapper.instance().handleDefaultProjectVisibilityChange('private'); + + expect(changeProjectDefaultVisibility).toBeCalledWith('private'); + await waitAndUpdate(wrapper); + expect(wrapper.state().defaultProjectVisibility).toBe('private'); +}); + it('loads more', () => { const wrapper = shallowRender(); wrapper.find('ListFooter').prop('loadMore')(); @@ -136,21 +162,11 @@ it('creates project', () => { expect(wrapper.find('CreateProjectForm').exists()).toBe(false); }); -it('changes default project visibility', () => { - const onVisibilityChange = jest.fn(); - const wrapper = shallowRender({ onVisibilityChange }); - wrapper.find('Header').prop('onVisibilityChange')('private'); - expect(onVisibilityChange).toBeCalledWith('private'); -}); - function shallowRender(props?: { [P in keyof Props]?: Props[P] }) { return shallow( ); diff --git a/server/sonar-web/src/main/js/apps/projectsManagement/__tests__/ChangeDefaultVisibilityForm-test.tsx b/server/sonar-web/src/main/js/apps/projectsManagement/__tests__/ChangeDefaultVisibilityForm-test.tsx index 34fbd344a8e..caafbd74c3f 100644 --- a/server/sonar-web/src/main/js/apps/projectsManagement/__tests__/ChangeDefaultVisibilityForm-test.tsx +++ b/server/sonar-web/src/main/js/apps/projectsManagement/__tests__/ChangeDefaultVisibilityForm-test.tsx @@ -21,22 +21,8 @@ import { shallow } from 'enzyme'; import * as React from 'react'; import Radio from 'sonar-ui-common/components/controls/Radio'; import { click } from 'sonar-ui-common/helpers/testUtils'; -import { mockOrganization } from '../../../helpers/testMocks'; import ChangeDefaultVisibilityForm from '../ChangeDefaultVisibilityForm'; -const organization: T.Organization = mockOrganization({ - canUpdateProjectsVisibilityToPrivate: true, - projectVisibility: 'public' -}); - -it('renders disabled', () => { - expect( - shallowRender({ - organization: { ...organization, canUpdateProjectsVisibilityToPrivate: false } - }) - ).toMatchSnapshot(); -}); - it('closes', () => { const onClose = jest.fn(); const wrapper = shallowRender({ onClose }); @@ -63,9 +49,9 @@ it('changes visibility', () => { function shallowRender(props: Partial = {}) { return shallow( ); diff --git a/server/sonar-web/src/main/js/apps/projectsManagement/__tests__/CreateProjectForm-test.tsx b/server/sonar-web/src/main/js/apps/projectsManagement/__tests__/CreateProjectForm-test.tsx index c135c2be1b1..3f752cea255 100644 --- a/server/sonar-web/src/main/js/apps/projectsManagement/__tests__/CreateProjectForm-test.tsx +++ b/server/sonar-web/src/main/js/apps/projectsManagement/__tests__/CreateProjectForm-test.tsx @@ -31,19 +31,12 @@ import CreateProjectForm from '../CreateProjectForm'; const createProject = require('../../../api/components').createProject as jest.Mock; -const organization: T.Organization = { - actions: { admin: true }, - key: 'org', - name: 'org', - projectVisibility: 'public' -}; - it('creates project', async () => { const wrapper = shallow( ); (wrapper.instance() as CreateProjectForm).mounted = true; diff --git a/server/sonar-web/src/main/js/apps/projectsManagement/__tests__/Header-test.tsx b/server/sonar-web/src/main/js/apps/projectsManagement/__tests__/Header-test.tsx index 3ca70e81917..c114a0d1362 100644 --- a/server/sonar-web/src/main/js/apps/projectsManagement/__tests__/Header-test.tsx +++ b/server/sonar-web/src/main/js/apps/projectsManagement/__tests__/Header-test.tsx @@ -24,14 +24,11 @@ import Header, { Props } from '../Header'; jest.mock('../../../helpers/system', () => ({ isSonarCloud: jest.fn().mockReturnValue(false) })); -const organization: T.Organization = { - key: 'org', - name: 'org', - projectVisibility: 'public' -}; - it('renders', () => { - expect(shallowRender()).toMatchSnapshot(); + expect(shallowRender()).toMatchSnapshot('default'); + expect(shallowRender({ defaultProjectVisibility: undefined })).toMatchSnapshot( + 'undefined visibility' + ); }); it('creates project', () => { @@ -42,15 +39,15 @@ it('creates project', () => { }); it('changes default visibility', () => { - const onVisibilityChange = jest.fn(); - const wrapper = shallowRender({ onVisibilityChange }); + const onChangeDefaultProjectVisibility = jest.fn(); + const wrapper = shallowRender({ onChangeDefaultProjectVisibility }); click(wrapper.find('.js-change-visibility')); const modalWrapper = wrapper.find('ChangeDefaultVisibilityForm'); expect(modalWrapper).toMatchSnapshot(); modalWrapper.prop('onConfirm')('private'); - expect(onVisibilityChange).toBeCalledWith('private'); + expect(onChangeDefaultProjectVisibility).toBeCalledWith('private'); modalWrapper.prop('onClose')(); wrapper.update(); @@ -60,10 +57,10 @@ it('changes default visibility', () => { function shallowRender(props?: { [P in keyof Props]?: Props[P] }) { return shallow(
); diff --git a/server/sonar-web/src/main/js/apps/projectsManagement/__tests__/__snapshots__/ChangeDefaultVisibilityForm-test.tsx.snap b/server/sonar-web/src/main/js/apps/projectsManagement/__tests__/__snapshots__/ChangeDefaultVisibilityForm-test.tsx.snap index 756189b1ca5..d735f686fb6 100644 --- a/server/sonar-web/src/main/js/apps/projectsManagement/__tests__/__snapshots__/ChangeDefaultVisibilityForm-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/projectsManagement/__tests__/__snapshots__/ChangeDefaultVisibilityForm-test.tsx.snap @@ -21,7 +21,6 @@ exports[`changes visibility 1`] = ` > @@ -41,7 +40,6 @@ exports[`changes visibility 1`] = ` > @@ -101,7 +99,6 @@ exports[`changes visibility 2`] = ` > @@ -121,7 +118,6 @@ exports[`changes visibility 2`] = ` > @@ -159,78 +155,3 @@ exports[`changes visibility 2`] = `
`; - -exports[`renders disabled 1`] = ` - -
-

- organization.change_visibility_form.header -

-
-
-
- -
- visibility.public -

- visibility.public.description.short -

-
-
-
-
- -
- visibility.private -

- visibility.private.description.short -

-
-
-
-
-
- - - cancel - -
-
-`; diff --git a/server/sonar-web/src/main/js/apps/projectsManagement/__tests__/__snapshots__/CreateProjectForm-test.tsx.snap b/server/sonar-web/src/main/js/apps/projectsManagement/__tests__/__snapshots__/CreateProjectForm-test.tsx.snap index bf16aa754b7..a5346ffd55e 100644 --- a/server/sonar-web/src/main/js/apps/projectsManagement/__tests__/__snapshots__/CreateProjectForm-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/projectsManagement/__tests__/__snapshots__/CreateProjectForm-test.tsx.snap @@ -73,6 +73,7 @@ exports[`creates project 1`] = ` visibility `; -exports[`renders 1`] = ` +exports[`renders: default 1`] = `
@@ -57,3 +51,47 @@ exports[`renders 1`] = `

`; + +exports[`renders: undefined visibility 1`] = ` +
+

+ projects_management +

+
+ + + organization.default_visibility_of_new_projects + + + — + + + + + +
+

+ projects_management.page.description +

+
+`; diff --git a/server/sonar-web/src/main/js/apps/projectsManagement/routes.ts b/server/sonar-web/src/main/js/apps/projectsManagement/routes.ts index 729a854fd60..d82abd3b146 100644 --- a/server/sonar-web/src/main/js/apps/projectsManagement/routes.ts +++ b/server/sonar-web/src/main/js/apps/projectsManagement/routes.ts @@ -21,7 +21,7 @@ import { lazyLoadComponent } from 'sonar-ui-common/components/lazyLoadComponent' const routes = [ { - indexRoute: { component: lazyLoadComponent(() => import('./AppContainer')) } + indexRoute: { component: lazyLoadComponent(() => import('./App')) } } ]; diff --git a/server/sonar-web/src/main/js/store/rootActions.ts b/server/sonar-web/src/main/js/store/rootActions.ts index c6471073c65..70d9b2a4911 100644 --- a/server/sonar-web/src/main/js/store/rootActions.ts +++ b/server/sonar-web/src/main/js/store/rootActions.ts @@ -22,7 +22,7 @@ import { Dispatch } from 'redux'; import * as auth from '../api/auth'; import { getLanguages } from '../api/languages'; import { getAllMetrics } from '../api/metrics'; -import { getOrganization, getOrganizationNavigation } from '../api/organizations'; +import { getOrganization } from '../api/organizations'; import { getQualityGateProjectStatus } from '../api/quality-gates'; import { getBranchLikeQuery } from '../helpers/branch-like'; import { extractStatusConditionsFromProjectStatus } from '../helpers/qualityGates'; @@ -38,7 +38,9 @@ export function fetchLanguages() { return (dispatch: Dispatch) => { getLanguages().then( languages => dispatch(receiveLanguages(languages)), - () => {} + () => { + /* do nothing */ + } ); }; } @@ -47,20 +49,18 @@ export function fetchMetrics() { return (dispatch: Dispatch) => { getAllMetrics().then( metrics => dispatch(receiveMetrics(metrics)), - () => {} + () => { + /* do nothing */ + } ); }; } -export const fetchOrganization = (key: string) => (dispatch: Dispatch) => { - return Promise.all([getOrganization(key), getOrganizationNavigation(key)]).then( - ([organization, navigation]) => { - if (organization) { - const organizationWithPermissions = { ...organization, ...navigation }; - dispatch(receiveOrganizations([organizationWithPermissions])); - } - } - ); +export const fetchOrganization = (key: string) => async (dispatch: Dispatch) => { + const organization = await getOrganization(key); + if (organization) { + dispatch(receiveOrganizations([organization])); + } }; export function fetchBranchStatus(branchLike: BranchLike, projectKey: string) { diff --git a/server/sonar-web/src/main/js/types/settings.ts b/server/sonar-web/src/main/js/types/settings.ts index 8ad3ca4df61..8588f8b4a29 100644 --- a/server/sonar-web/src/main/js/types/settings.ts +++ b/server/sonar-web/src/main/js/types/settings.ts @@ -18,5 +18,6 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ export const enum SettingsKey { - DaysBeforeDeletingInactiveBranchesAndPRs = 'sonar.dbcleaner.daysBeforeDeletingInactiveBranchesAndPRs' + DaysBeforeDeletingInactiveBranchesAndPRs = 'sonar.dbcleaner.daysBeforeDeletingInactiveBranchesAndPRs', + DefaultProjectVisibility = 'projects.default.visibility' } -- 2.39.5