From 965717195e58808778753edd0daa0e3d9e831cdd Mon Sep 17 00:00:00 2001 From: Julien HENRY Date: Tue, 27 Mar 2018 11:52:20 +0200 Subject: Introduce Bitbucket Cloud Application SONAR-10514 Bitbucket Cloud application install/uninstall * Bitbucket Cloud /install WS * Expose Bitbucket application descriptor as WS * Implement WS /integration/bitbucketcloud/uninstall SONAR-10517 Bitbucket Cloud settings widget * Create Bitbucket Cloud module * Create Bitbucket Setting widget * Bitbucket settings widget require SC authentication * Add WS /integration/bitbucketcloud/repo_config * Add WS /integration/bitbucketcloud/bind_repo * Add WS /integration/bitbucketcloud/after_login SONAR-10516 Bitbucket Cloud repository widget * Add WS /integration/bitbucketcloud/repo_widget * Add WS /integration/bitbucketcloud/repo_widget_data BRANCH-59, BRANCH-60 Bitbucket Cloud PR decoration SONAR-10605 Bitbucket Cloud PR widget * Add integration/bitbucketcloud/pr_widget endpoint * Add integration/bitbucketcloud/pr_widget_data endpoint --- server/sonar-web/src/main/js/api/components.ts | 10 ++- server/sonar-web/src/main/js/app/types.ts | 13 ++++ .../src/main/js/app/utils/startReactApp.js | 2 + .../main/js/apps/account/projects/ProjectCard.tsx | 18 ++--- .../src/main/js/apps/account/projects/Projects.tsx | 9 +-- .../js/apps/account/projects/ProjectsContainer.tsx | 45 ++++------- .../account/projects/__tests__/ProjectCard-test.js | 86 ---------------------- .../projects/__tests__/ProjectCard-test.tsx | 86 ++++++++++++++++++++++ .../account/projects/__tests__/Projects-test.js | 76 ------------------- .../account/projects/__tests__/Projects-test.tsx | 59 +++++++++++++++ .../src/main/js/apps/account/projects/types.ts | 32 -------- .../js/apps/tutorials/onboarding/Onboarding.js | 17 +++-- .../tutorials/onboarding/OnboardingContainer.js | 12 +-- .../apps/tutorials/onboarding/OnboardingPage.tsx | 47 ++++++++++++ .../onboarding/__tests__/Onboarding-test.js | 17 +---- .../__snapshots__/Onboarding-test.js.snap | 14 +--- .../src/main/js/components/common/BranchStatus.tsx | 21 ++---- server/sonar-web/src/main/js/helpers/branches.ts | 12 +++ 18 files changed, 280 insertions(+), 296 deletions(-) delete mode 100644 server/sonar-web/src/main/js/apps/account/projects/__tests__/ProjectCard-test.js create mode 100644 server/sonar-web/src/main/js/apps/account/projects/__tests__/ProjectCard-test.tsx delete mode 100644 server/sonar-web/src/main/js/apps/account/projects/__tests__/Projects-test.js create mode 100644 server/sonar-web/src/main/js/apps/account/projects/__tests__/Projects-test.tsx delete mode 100644 server/sonar-web/src/main/js/apps/account/projects/types.ts create mode 100644 server/sonar-web/src/main/js/apps/tutorials/onboarding/OnboardingPage.tsx (limited to 'server/sonar-web/src/main/js') diff --git a/server/sonar-web/src/main/js/api/components.ts b/server/sonar-web/src/main/js/api/components.ts index 78e2b72d96a..3d7504db32f 100644 --- a/server/sonar-web/src/main/js/api/components.ts +++ b/server/sonar-web/src/main/js/api/components.ts @@ -19,7 +19,7 @@ */ import { getJSON, postJSON, post, RequestData } from '../helpers/request'; import throwGlobalError from '../app/utils/throwGlobalError'; -import { Paging, Visibility, BranchParameters } from '../app/types'; +import { Paging, Visibility, BranchParameters, MyProject } from '../app/types'; export interface BaseSearchProjectsParameters { analyzedBefore?: string; @@ -145,9 +145,11 @@ export function getComponentData(data: { component: string } & BranchParameters) return getComponentShow(data).then(r => r.component); } -export function getMyProjects(data: RequestData): Promise { - const url = '/api/projects/search_my_projects'; - return getJSON(url, data); +export function getMyProjects(data: { + p?: number; + ps?: number; +}): Promise<{ paging: Paging; projects: MyProject[] }> { + return getJSON('/api/projects/search_my_projects', data); } export interface Component { diff --git a/server/sonar-web/src/main/js/app/types.ts b/server/sonar-web/src/main/js/app/types.ts index 8fa11ed7fb1..1967bb2497e 100644 --- a/server/sonar-web/src/main/js/app/types.ts +++ b/server/sonar-web/src/main/js/app/types.ts @@ -312,6 +312,19 @@ export interface Metric { type: string; } +export interface MyProject { + description?: string; + key: string; + lastAnalysisDate?: string; + links: Array<{ + name: string; + type: string; + href: string; + }>; + name: string; + qualityGate?: string; +} + export interface Notification { channel: string; organization?: string; diff --git a/server/sonar-web/src/main/js/app/utils/startReactApp.js b/server/sonar-web/src/main/js/app/utils/startReactApp.js index 1b0d9750a00..a013773e344 100644 --- a/server/sonar-web/src/main/js/app/utils/startReactApp.js +++ b/server/sonar-web/src/main/js/app/utils/startReactApp.js @@ -41,6 +41,7 @@ import GlobalPageExtension from '../components/extensions/GlobalPageExtension'; import GlobalAdminPageExtension from '../components/extensions/GlobalAdminPageExtension'; import MarkdownHelp from '../components/MarkdownHelp'; import NotFound from '../components/NotFound'; +import OnboardingPage from '../../apps/tutorials/onboarding/OnboardingPage'; import aboutRoutes from '../../apps/about/routes'; import accountRoutes from '../../apps/account/routes'; import backgroundTasksRoutes from '../../apps/background-tasks/routes'; @@ -179,6 +180,7 @@ const startReactApp = () => { + diff --git a/server/sonar-web/src/main/js/apps/account/projects/ProjectCard.tsx b/server/sonar-web/src/main/js/apps/account/projects/ProjectCard.tsx index 15d180785b7..f05af84c229 100644 --- a/server/sonar-web/src/main/js/apps/account/projects/ProjectCard.tsx +++ b/server/sonar-web/src/main/js/apps/account/projects/ProjectCard.tsx @@ -20,29 +20,29 @@ import * as React from 'react'; import { sortBy } from 'lodash'; import { Link } from 'react-router'; -import { Project } from './types'; import DateFromNow from '../../../components/intl/DateFromNow'; import DateTimeFormatter from '../../../components/intl/DateTimeFormatter'; import Level from '../../../components/ui/Level'; import Tooltip from '../../../components/controls/Tooltip'; import { translateWithParameters, translate } from '../../../helpers/l10n'; +import { MyProject } from '../../../app/types'; interface Props { - project: Project; + project: MyProject; } export default function ProjectCard({ project }: Props) { - const isAnalyzed = project.lastAnalysisDate != null; const links = sortBy(project.links, 'type'); + const { lastAnalysisDate } = project; return (
diff --git a/server/sonar-web/src/main/js/apps/account/projects/ProjectsContainer.tsx b/server/sonar-web/src/main/js/apps/account/projects/ProjectsContainer.tsx index 923c7c9acb8..a5d62ac64a3 100644 --- a/server/sonar-web/src/main/js/apps/account/projects/ProjectsContainer.tsx +++ b/server/sonar-web/src/main/js/apps/account/projects/ProjectsContainer.tsx @@ -22,22 +22,18 @@ import Helmet from 'react-helmet'; import Projects from './Projects'; import { getMyProjects } from '../../../api/components'; import { translate } from '../../../helpers/l10n'; +import { MyProject } from '../../../app/types'; interface State { loading: boolean; page: number; - projects?: any[]; - query: string; + projects?: MyProject[]; total?: number; } export default class ProjectsContainer extends React.PureComponent<{}, State> { mounted = false; - state: State = { - loading: true, - page: 1, - query: '' - }; + state: State = { loading: true, page: 1 }; componentDidMount() { this.mounted = true; @@ -48,30 +44,22 @@ export default class ProjectsContainer extends React.PureComponent<{}, State> { this.mounted = false; } - loadProjects(page = this.state.page, query = this.state.query) { + loadProjects(page = this.state.page) { this.setState({ loading: true }); - const data: { [p: string]: any } = { ps: 100 }; - if (page > 1) { - data.p = page; - } - if (query) { - data.q = query; - } - return getMyProjects(data).then((r: any) => { - const projects = page > 1 ? [...(this.state.projects || []), ...r.projects] : r.projects; - this.setState({ - projects, - query, + const data = { p: page, ps: 100 }; + return getMyProjects(data).then(({ paging, projects }) => { + this.setState(state => ({ + projects: page > 1 ? [...(state.projects || []), ...projects] : projects, loading: false, - page: r.paging.pageIndex, - total: r.paging.total - }); + page: paging.pageIndex, + total: paging.total + })); }); } - loadMore = () => this.loadProjects(this.state.page + 1); - - search = (query: string) => this.loadProjects(1, query); + loadMore = () => { + this.loadProjects(this.state.page + 1); + }; render() { const helmet = ; @@ -89,11 +77,10 @@ export default class ProjectsContainer extends React.PureComponent<{}, State> {
{helmet}
); diff --git a/server/sonar-web/src/main/js/apps/account/projects/__tests__/ProjectCard-test.js b/server/sonar-web/src/main/js/apps/account/projects/__tests__/ProjectCard-test.js deleted file mode 100644 index c714da617dc..00000000000 --- a/server/sonar-web/src/main/js/apps/account/projects/__tests__/ProjectCard-test.js +++ /dev/null @@ -1,86 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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 React from 'react'; -import { shallow } from 'enzyme'; -import { Link } from 'react-router'; -import ProjectCard from '../ProjectCard'; -import Level from '../../../../components/ui/Level'; - -const BASE = { id: 'id', key: 'key', name: 'name', links: [] }; - -it('should render key and name', () => { - const project = { ...BASE }; - const output = shallow(); - expect(output.find('.account-project-key').text()).toBe('key'); - expect( - output - .find('.account-project-name') - .find(Link) - .prop('children') - ).toBe('name'); -}); - -it('should render description', () => { - const project = { ...BASE, description: 'bla' }; - const output = shallow(); - expect(output.find('.account-project-description').text()).toBe('bla'); -}); - -it('should not render optional fields', () => { - const project = { ...BASE }; - const output = shallow(); - expect(output.find('.account-project-description').length).toBe(0); - expect(output.find('.account-project-quality-gate').length).toBe(0); - expect(output.find('.account-project-links').length).toBe(0); -}); - -it('should render analysis date', () => { - const project = { ...BASE, lastAnalysisDate: '2016-05-17' }; - const output = shallow(); - expect(output.find('.account-project-analysis DateFromNow')).toHaveLength(1); -}); - -it('should not render analysis date', () => { - const project = { ...BASE }; - const output = shallow(); - expect(output.find('.account-project-analysis').text()).toContain( - 'my_account.projects.never_analyzed' - ); -}); - -it('should render quality gate status', () => { - const project = { ...BASE, qualityGate: 'ERROR' }; - const output = shallow(); - expect( - output - .find('.account-project-quality-gate') - .find(Level) - .prop('level') - ).toBe('ERROR'); -}); - -it('should render links', () => { - const project = { - ...BASE, - links: [{ name: 'n', type: 't', href: 'h' }] - }; - const output = shallow(); - expect(output.find('.account-project-links').find('li').length).toBe(1); -}); diff --git a/server/sonar-web/src/main/js/apps/account/projects/__tests__/ProjectCard-test.tsx b/server/sonar-web/src/main/js/apps/account/projects/__tests__/ProjectCard-test.tsx new file mode 100644 index 00000000000..924a53f21e1 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/account/projects/__tests__/ProjectCard-test.tsx @@ -0,0 +1,86 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 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 { shallow } from 'enzyme'; +import { Link } from 'react-router'; +import ProjectCard from '../ProjectCard'; +import Level from '../../../../components/ui/Level'; + +const BASE = { key: 'key', links: [], name: 'name' }; + +it('should render key and name', () => { + const project = { ...BASE }; + const output = shallow(); + expect(output.find('.account-project-key').text()).toBe('key'); + expect( + output + .find('.account-project-name') + .find(Link) + .prop('children') + ).toBe('name'); +}); + +it('should render description', () => { + const project = { ...BASE, description: 'bla' }; + const output = shallow(); + expect(output.find('.account-project-description').text()).toBe('bla'); +}); + +it('should not render optional fields', () => { + const project = { ...BASE }; + const output = shallow(); + expect(output.find('.account-project-description').length).toBe(0); + expect(output.find('.account-project-quality-gate').length).toBe(0); + expect(output.find('.account-project-links').length).toBe(0); +}); + +it('should render analysis date', () => { + const project = { ...BASE, lastAnalysisDate: '2016-05-17' }; + const output = shallow(); + expect(output.find('.account-project-analysis DateFromNow')).toHaveLength(1); +}); + +it('should not render analysis date', () => { + const project = { ...BASE }; + const output = shallow(); + expect(output.find('.account-project-analysis').text()).toContain( + 'my_account.projects.never_analyzed' + ); +}); + +it('should render quality gate status', () => { + const project = { ...BASE, qualityGate: 'ERROR' }; + const output = shallow(); + expect( + output + .find('.account-project-quality-gate') + .find(Level) + .prop('level') + ).toBe('ERROR'); +}); + +it('should render links', () => { + const project = { + ...BASE, + links: [{ name: 'n', type: 't', href: 'h' }] + }; + const output = shallow(); + expect(output.find('.account-project-links').find('li').length).toBe(1); +}); diff --git a/server/sonar-web/src/main/js/apps/account/projects/__tests__/Projects-test.js b/server/sonar-web/src/main/js/apps/account/projects/__tests__/Projects-test.js deleted file mode 100644 index a11086a28ce..00000000000 --- a/server/sonar-web/src/main/js/apps/account/projects/__tests__/Projects-test.js +++ /dev/null @@ -1,76 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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 React from 'react'; -import { shallow } from 'enzyme'; -import Projects from '../Projects'; -import ProjectCard from '../ProjectCard'; -import ListFooter from '../../../../components/controls/ListFooter'; - -it('should render list of ProjectCards', () => { - const projects = [ - { id: 'id1', key: 'key1', name: 'name1', links: [] }, - { id: 'id2', key: 'key2', name: 'name2', links: [] } - ]; - - const output = shallow( - true} - loadMore={() => true} - /> - ); - - expect(output.find(ProjectCard).length).toBe(2); -}); - -it('should render ListFooter', () => { - const projects = [ - { id: 'id1', key: 'key1', name: 'name1', links: [] }, - { id: 'id2', key: 'key2', name: 'name2', links: [] } - ]; - const loadMore = jest.fn(); - - const footer = shallow( - true} - loadMore={loadMore} - /> - ).find(ListFooter); - - expect(footer.length).toBe(1); - expect(footer.prop('count')).toBe(2); - expect(footer.prop('total')).toBe(5); - expect(footer.prop('loadMore')).toBe(loadMore); -}); - -it('should render when no results', () => { - const output = shallow( - true} loadMore={() => true} /> - ); - - expect(output.find('.js-no-results').length).toBe(1); - expect(output.find(ProjectCard).length).toBe(0); - expect(output.find(ListFooter).length).toBe(0); -}); diff --git a/server/sonar-web/src/main/js/apps/account/projects/__tests__/Projects-test.tsx b/server/sonar-web/src/main/js/apps/account/projects/__tests__/Projects-test.tsx new file mode 100644 index 00000000000..0d2cf182fad --- /dev/null +++ b/server/sonar-web/src/main/js/apps/account/projects/__tests__/Projects-test.tsx @@ -0,0 +1,59 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 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 { shallow } from 'enzyme'; +import Projects from '../Projects'; +import ProjectCard from '../ProjectCard'; +import ListFooter from '../../../../components/controls/ListFooter'; + +const PROJECTS = [ + { key: 'key1', links: [], name: 'name1' }, + { key: 'key2', links: [], name: 'name2' } +]; +it('should render list of ProjectCards', () => { + const output = shallow( + true} loading={false} projects={PROJECTS} total={5} /> + ); + + expect(output.find(ProjectCard).length).toBe(2); +}); + +it('should render ListFooter', () => { + const loadMore = jest.fn(); + + const footer = shallow( + + ).find(ListFooter); + + expect(footer.length).toBe(1); + expect(footer.prop('count')).toBe(2); + expect(footer.prop('total')).toBe(5); + expect(footer.prop('loadMore')).toBe(loadMore); +}); + +it('should render when no results', () => { + const output = shallow( + true} loading={false} projects={[]} total={0} /> + ); + + expect(output.find('.js-no-results').length).toBe(1); + expect(output.find(ProjectCard).length).toBe(0); + expect(output.find(ListFooter).length).toBe(0); +}); diff --git a/server/sonar-web/src/main/js/apps/account/projects/types.ts b/server/sonar-web/src/main/js/apps/account/projects/types.ts deleted file mode 100644 index 930334bea55..00000000000 --- a/server/sonar-web/src/main/js/apps/account/projects/types.ts +++ /dev/null @@ -1,32 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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. - */ -export interface Project { - id: string; - key: string; - name: string; - lastAnalysisDate: string; - description: string; - links: Array<{ - href: string; - name: string; - type: string; - }>; - qualityGate: string; -} diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/Onboarding.js b/server/sonar-web/src/main/js/apps/tutorials/onboarding/Onboarding.js index 2b7e5f2bca5..e7c31f647cc 100644 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/Onboarding.js +++ b/server/sonar-web/src/main/js/apps/tutorials/onboarding/Onboarding.js @@ -34,10 +34,10 @@ import './styles.css'; /*:: type Props = {| + className?: string, currentUser: { login: string, isLoggedIn: boolean }, onFinish: () => void, - organizationsEnabled: boolean, - sonarCloud: boolean + organizationsEnabled: boolean |}; */ @@ -58,6 +58,7 @@ export default class Onboarding extends React.PureComponent { /*:: state: State; */ static contextTypes = { + onSonarCloud: PropTypes.bool, router: PropTypes.object }; @@ -144,13 +145,13 @@ export default class Onboarding extends React.PureComponent { return null; } - const { organizationsEnabled, sonarCloud } = this.props; + const { onSonarCloud } = this.context; + const { organizationsEnabled } = this.props; const { step, token } = this.state; - let stepNumber = 1; return ( -
+
{transformedMessage => } @@ -170,7 +171,7 @@ export default class Onboarding extends React.PureComponent { )}

{translate( - sonarCloud ? 'tutorials.find_it_back_in_plus' : 'tutorials.find_it_back_in_help' + onSonarCloud ? 'tutorials.find_it_back_in_plus' : 'tutorials.find_it_back_in_help' )}

@@ -205,9 +206,9 @@ export default class Onboarding extends React.PureComponent { diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/OnboardingContainer.js b/server/sonar-web/src/main/js/apps/tutorials/onboarding/OnboardingContainer.js index 18cc38d1f5c..cf27d5dd333 100644 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/OnboardingContainer.js +++ b/server/sonar-web/src/main/js/apps/tutorials/onboarding/OnboardingContainer.js @@ -20,19 +20,13 @@ // @flow import { connect } from 'react-redux'; import Onboarding from './Onboarding'; -import { - getCurrentUser, - areThereCustomOrganizations, - getGlobalSettingValue -} from '../../../store/rootReducer'; +import { getCurrentUser, areThereCustomOrganizations } from '../../../store/rootReducer'; const mapStateToProps = state => { - const sonarCloudSetting = getGlobalSettingValue(state, 'sonar.sonarcloud.enabled'); - return { + className: 'modal-container', currentUser: getCurrentUser(state), - organizationsEnabled: areThereCustomOrganizations(state), - sonarCloud: sonarCloudSetting != null && sonarCloudSetting.value === 'true' + organizationsEnabled: areThereCustomOrganizations(state) }; }; diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/OnboardingPage.tsx b/server/sonar-web/src/main/js/apps/tutorials/onboarding/OnboardingPage.tsx new file mode 100644 index 00000000000..971ae8bddff --- /dev/null +++ b/server/sonar-web/src/main/js/apps/tutorials/onboarding/OnboardingPage.tsx @@ -0,0 +1,47 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 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 * as PropTypes from 'prop-types'; +import { connect } from 'react-redux'; +import OnboardingModal from './OnboardingModal'; +import { skipOnboarding } from '../../../store/users/actions'; + +interface DispatchProps { + skipOnboarding: () => void; +} + +export class OnboardingPage extends React.PureComponent { + static contextTypes = { + router: PropTypes.object.isRequired + }; + + onSkipOnboardingTutorial = () => { + this.props.skipOnboarding(); + this.context.router.replace('/'); + }; + + render() { + return ; + } +} + +const mapDispatchToProps: DispatchProps = { skipOnboarding }; + +export default connect<{}, DispatchProps, {}>(null, mapDispatchToProps)(OnboardingPage); diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/Onboarding-test.js b/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/Onboarding-test.js index 4d66e667374..2d5019ae82d 100644 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/Onboarding-test.js +++ b/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/Onboarding-test.js @@ -32,10 +32,10 @@ const currentUser = { login: 'admin', isLoggedIn: true }; it('guides for on-premise', () => { const wrapper = shallow( ); expect(wrapper).toMatchSnapshot(); @@ -48,12 +48,8 @@ it('guides for on-premise', () => { it('guides for sonarcloud', () => { const wrapper = shallow( - + , + { context: { onSonarCloud: true } } ); expect(wrapper).toMatchSnapshot(); @@ -71,12 +67,7 @@ it('guides for sonarcloud', () => { it('finishes', () => { const onFinish = jest.fn(); const wrapper = mount( - + ); click(wrapper.find('.js-skip')); return doAsync(() => { diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/__snapshots__/Onboarding-test.js.snap b/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/__snapshots__/Onboarding-test.js.snap index 373e5949514..997502681fe 100644 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/__snapshots__/Onboarding-test.js.snap +++ b/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/__snapshots__/Onboarding-test.js.snap @@ -59,7 +59,6 @@ exports[`guides for on-premise 1`] = ` onFinish={[Function]} onReset={[Function]} open={false} - sonarCloud={false} stepNumber={2} />
@@ -125,7 +124,6 @@ exports[`guides for on-premise 2`] = ` onFinish={[Function]} onReset={[Function]} open={true} - sonarCloud={false} stepNumber={2} token="abcd1234" /> @@ -134,9 +132,7 @@ exports[`guides for on-premise 2`] = ` `; exports[`guides for sonarcloud 1`] = ` -
+
@@ -213,9 +209,7 @@ exports[`guides for sonarcloud 1`] = ` `; exports[`guides for sonarcloud 2`] = ` -
+
@@ -293,9 +287,7 @@ exports[`guides for sonarcloud 2`] = ` `; exports[`guides for sonarcloud 3`] = ` -
+
diff --git a/server/sonar-web/src/main/js/components/common/BranchStatus.tsx b/server/sonar-web/src/main/js/components/common/BranchStatus.tsx index 1738e5c1fa1..2fc23b47849 100644 --- a/server/sonar-web/src/main/js/components/common/BranchStatus.tsx +++ b/server/sonar-web/src/main/js/components/common/BranchStatus.tsx @@ -26,7 +26,12 @@ import HelpTooltip from '../controls/HelpTooltip'; import Tooltip from '../controls/Tooltip'; import VulnerabilityIcon from '../icons-components/VulnerabilityIcon'; import { BranchLike } from '../../app/types'; -import { isShortLivingBranch, isPullRequest, isLongLivingBranch } from '../../helpers/branches'; +import { + getBranchQualityGateColor, + isShortLivingBranch, + isPullRequest, + isLongLivingBranch +} from '../../helpers/branches'; import { translateWithParameters } from '../../helpers/l10n'; import { formatMeasure } from '../../helpers/measures'; import './BranchStatus.css'; @@ -45,7 +50,7 @@ export default function BranchStatus({ branchLike, concise = false }: Props) { const totalIssues = branchLike.status.bugs + branchLike.status.vulnerabilities + branchLike.status.codeSmells; const status = branchLike.status.qualityGateStatus; - const indicatorColor = getQualityGateColor(status); + const indicatorColor = getBranchQualityGateColor(status); const shouldDisplayHelper = status === 'OK' && totalIssues > 0; const label = @@ -102,15 +107,3 @@ export default function BranchStatus({ branchLike, concise = false }: Props) { return null; } } - -function getQualityGateColor(status: string) { - let indicatorColor = 'gray'; - if (status === 'ERROR') { - indicatorColor = 'red'; - } else if (status === 'WARN') { - indicatorColor = 'orange'; - } else if (status === 'OK') { - indicatorColor = 'green'; - } - return indicatorColor; -} diff --git a/server/sonar-web/src/main/js/helpers/branches.ts b/server/sonar-web/src/main/js/helpers/branches.ts index cb930b0a80b..6b4507eddcd 100644 --- a/server/sonar-web/src/main/js/helpers/branches.ts +++ b/server/sonar-web/src/main/js/helpers/branches.ts @@ -69,6 +69,18 @@ export function getBranchLikeKey(branchLike: BranchLike) { return isPullRequest(branchLike) ? `pull-request-${branchLike.key}` : `branch-${branchLike.name}`; } +export function getBranchQualityGateColor(status: string) { + let indicatorColor = 'gray'; + if (status === 'ERROR') { + indicatorColor = 'red'; + } else if (status === 'WARN') { + indicatorColor = 'orange'; + } else if (status === 'OK') { + indicatorColor = 'green'; + } + return indicatorColor; +} + export function isSameBranchLike(a: BranchLike | undefined, b: BranchLike | undefined) { // main branches are always equal if (isMainBranch(a) && isMainBranch(b)) { -- cgit v1.2.3