From fed59c4f4663f6dfad64d2742712d53c090ea4b3 Mon Sep 17 00:00:00 2001 From: Stas Vilchik Date: Wed, 11 Oct 2017 16:18:48 +0200 Subject: [PATCH] SONAR-9867 Add button promoting governance on background tasks page --- server/sonar-web/src/main/js/api/ce.ts | 2 +- .../nav/component/NoBranchSupportPopup.tsx | 2 +- .../NoBranchSupportPopup-test.tsx.snap | 2 +- .../components/{Header.js => Header.tsx} | 13 ++-- .../components/NoWorkersSupportPopup.tsx | 44 +++++++++++++ .../components/{Workers.js => Workers.tsx} | 63 ++++++++++++++----- .../{WorkersForm.js => WorkersForm.tsx} | 39 +++++------- .../{Workers-test.js => Workers-test.tsx} | 9 ++- ...rkersForm-test.js => WorkersForm-test.tsx} | 25 ++++---- ...ers-test.js.snap => Workers-test.tsx.snap} | 40 +++++++++++- ...test.js.snap => WorkersForm-test.tsx.snap} | 40 ++++++------ .../main/less/components/bubble-popup.less | 4 +- .../resources/org/sonar/l10n/core.properties | 5 +- 13 files changed, 193 insertions(+), 95 deletions(-) rename server/sonar-web/src/main/js/apps/background-tasks/components/{Header.js => Header.tsx} (90%) create mode 100644 server/sonar-web/src/main/js/apps/background-tasks/components/NoWorkersSupportPopup.tsx rename server/sonar-web/src/main/js/apps/background-tasks/components/{Workers.js => Workers.tsx} (63%) rename server/sonar-web/src/main/js/apps/background-tasks/components/{WorkersForm.js => WorkersForm.tsx} (83%) rename server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/{Workers-test.js => Workers-test.tsx} (95%) rename server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/{WorkersForm-test.js => WorkersForm-test.tsx} (78%) rename server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/{Workers-test.js.snap => Workers-test.tsx.snap} (77%) rename server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/{WorkersForm-test.js.snap => WorkersForm-test.tsx.snap} (91%) diff --git a/server/sonar-web/src/main/js/api/ce.ts b/server/sonar-web/src/main/js/api/ce.ts index a61b0e2051b..33be5602977 100644 --- a/server/sonar-web/src/main/js/api/ce.ts +++ b/server/sonar-web/src/main/js/api/ce.ts @@ -81,7 +81,7 @@ export function getTypes(): Promise { return getJSON('/api/ce/task_types').then(r => r.taskTypes); } -export function getWorkers(): Promise<{ canSetWorkerCount: boolean; value: number } | Response> { +export function getWorkers(): Promise<{ canSetWorkerCount: boolean; value: number }> { return getJSON('/api/ce/worker_count').catch(throwGlobalError); } diff --git a/server/sonar-web/src/main/js/app/components/nav/component/NoBranchSupportPopup.tsx b/server/sonar-web/src/main/js/app/components/nav/component/NoBranchSupportPopup.tsx index 70cfb0edb28..35ac2dbcdd4 100644 --- a/server/sonar-web/src/main/js/app/components/nav/component/NoBranchSupportPopup.tsx +++ b/server/sonar-web/src/main/js/app/components/nav/component/NoBranchSupportPopup.tsx @@ -33,7 +33,7 @@ export default function NoBranchSupportPopup(props: Props) {

{translate('branches.no_support.header.text')}

- {translate('branches.learn_more')} + {translate('learn_more')} - branches.learn_more + learn_more

{translate('background_tasks.page')}

diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/NoWorkersSupportPopup.tsx b/server/sonar-web/src/main/js/apps/background-tasks/components/NoWorkersSupportPopup.tsx new file mode 100644 index 00000000000..c6e18f5c8a3 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/background-tasks/components/NoWorkersSupportPopup.tsx @@ -0,0 +1,44 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact 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 BubblePopup from '../../../components/common/BubblePopup'; +import { translate } from '../../../helpers/l10n'; + +interface Props { + popupPosition?: any; +} + +export default function NoWorkersSupportPopup(props: Props) { + return ( + +
+
{translate('background_tasks.add_more_workers')}
+

+ {translate('background_tasks.add_more_workers.text')} +

+

+ + {translate('learn_more')} + +

+
+ + ); +} diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/Workers.js b/server/sonar-web/src/main/js/apps/background-tasks/components/Workers.tsx similarity index 63% rename from server/sonar-web/src/main/js/apps/background-tasks/components/Workers.js rename to server/sonar-web/src/main/js/apps/background-tasks/components/Workers.tsx index 670cca4450b..9c51b4a9c10 100644 --- a/server/sonar-web/src/main/js/apps/background-tasks/components/Workers.js +++ b/server/sonar-web/src/main/js/apps/background-tasks/components/Workers.tsx @@ -17,28 +17,30 @@ * 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 WorkersForm from './WorkersForm'; +import NoWorkersSupportPopup from './NoWorkersSupportPopup'; import Tooltip from '../../../components/controls/Tooltip'; import { getWorkers } from '../../../api/ce'; import { translate } from '../../../helpers/l10n'; +import HelpIcon from '../../../components/icons-components/HelpIcon'; +import BubblePopupHelper from '../../../components/common/BubblePopupHelper'; -/*:: -type State = { - canSetWorkerCount: boolean, - formOpen: boolean, - loading: boolean, - workerCount: number -}; -*/ - -export default class Workers extends React.PureComponent { - /*:: mounted: boolean; */ - state /*: State */ = { +interface State { + canSetWorkerCount: boolean; + formOpen: boolean; + loading: boolean; + noSupportPopup: boolean; + workerCount: number; +} + +export default class Workers extends React.PureComponent<{}, State> { + mounted: boolean; + state: State = { canSetWorkerCount: false, formOpen: false, loading: true, + noSupportPopup: false, workerCount: 1 }; @@ -64,16 +66,30 @@ export default class Workers extends React.PureComponent { }); }; - closeForm = (newWorkerCount /*: ?number */) => + closeForm = (newWorkerCount?: number) => newWorkerCount ? this.setState({ formOpen: false, workerCount: newWorkerCount }) : this.setState({ formOpen: false }); - handleChangeClick = (event /*: Event */) => { + handleChangeClick = (event: React.SyntheticEvent) => { event.preventDefault(); this.setState({ formOpen: true }); }; + handleHelpClick = (event: React.SyntheticEvent) => { + event.preventDefault(); + event.stopPropagation(); + this.toggleNoSupportPopup(); + }; + + toggleNoSupportPopup = (show?: boolean) => { + if (show != undefined) { + this.setState({ noSupportPopup: show }); + } else { + this.setState(state => ({ noSupportPopup: !state.noSupportPopup })); + } + }; + render() { const { canSetWorkerCount, formOpen, loading, workerCount } = this.state; @@ -101,6 +117,21 @@ export default class Workers extends React.PureComponent { )} + {!loading && + !canSetWorkerCount && ( + + + + + } + togglePopup={this.toggleNoSupportPopup} + /> + + )} + {formOpen && } ); diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/WorkersForm.js b/server/sonar-web/src/main/js/apps/background-tasks/components/WorkersForm.tsx similarity index 83% rename from server/sonar-web/src/main/js/apps/background-tasks/components/WorkersForm.js rename to server/sonar-web/src/main/js/apps/background-tasks/components/WorkersForm.tsx index ded18f7c6c8..1d4854b74d2 100644 --- a/server/sonar-web/src/main/js/apps/background-tasks/components/WorkersForm.js +++ b/server/sonar-web/src/main/js/apps/background-tasks/components/WorkersForm.tsx @@ -17,36 +17,29 @@ * 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 Modal from 'react-modal'; -import Select from 'react-select'; +import * as Select from 'react-select'; import { times } from 'lodash'; import { setWorkerCount } from '../../../api/ce'; import { translate } from '../../../helpers/l10n'; const MAX_WORKERS = 10; -/*:: -type Props = { - onClose: (newWorkerCount?: number) => void, - workerCount: number -}; -*/ +interface Props { + onClose: (newWorkerCount?: number) => void; + workerCount: number; +} -/*:: -type State = { - newWorkerCount: number, - submitting: boolean -}; -*/ +interface State { + newWorkerCount: number; + submitting: boolean; +} -export default class WorkersForm extends React.PureComponent { - /*:: mounted: boolean; */ - /*:: props: Props; */ - /*:: state: State; */ +export default class WorkersForm extends React.PureComponent { + mounted: boolean; - constructor(props /*: Props */) { + constructor(props: Props) { super(props); this.state = { newWorkerCount: props.workerCount, @@ -64,10 +57,10 @@ export default class WorkersForm extends React.PureComponent { handleClose = () => this.props.onClose(); - handleWorkerCountChange = (option /*: { value: number } */) => + handleWorkerCountChange = (option: { value: number }) => this.setState({ newWorkerCount: option.value }); - handleSubmit = (event /*: Event */) => { + handleSubmit = (event: React.SyntheticEvent) => { event.preventDefault(); this.setState({ submitting: true }); const { newWorkerCount } = this.state; @@ -86,7 +79,7 @@ export default class WorkersForm extends React.PureComponent { }; render() { - const options = times(MAX_WORKERS).map((_, i) => ({ label: i + 1, value: i + 1 })); + const options = times(MAX_WORKERS).map((_, i) => ({ label: String(i + 1), value: i + 1 })); return ( { }); expect(wrapper).toMatchSnapshot(); - wrapper.setState({ canSetWorkerCount: false }); + wrapper.setState({ workerCount: 2 }); expect(wrapper).toMatchSnapshot(); - wrapper.setState({ workerCount: 2 }); + wrapper.setState({ canSetWorkerCount: false }); expect(wrapper).toMatchSnapshot(); }); @@ -66,7 +65,7 @@ it('updates worker count', () => { }); expect(wrapper).toMatchSnapshot(); - wrapper.find('WorkersForm').prop('onClose')(7); + wrapper.find('WorkersForm').prop('onClose')(7); wrapper.update(); expect(wrapper).toMatchSnapshot(); }); diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/WorkersForm-test.js b/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/WorkersForm-test.tsx similarity index 78% rename from server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/WorkersForm-test.js rename to server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/WorkersForm-test.tsx index f821ba6fb32..813eff21896 100644 --- a/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/WorkersForm-test.js +++ b/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/WorkersForm-test.tsx @@ -17,36 +17,33 @@ * 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 { shallow } from 'enzyme'; -import WorkersForm from '../WorkersForm'; -import { submit, doAsync } from '../../../../helpers/testUtils'; - jest.mock('../../../../api/ce', () => ({ setWorkerCount: () => Promise.resolve() })); +import * as React from 'react'; +import { shallow } from 'enzyme'; +import WorkersForm from '../WorkersForm'; +import { submit } from '../../../../helpers/testUtils'; + it('changes select', () => { const wrapper = shallow(); expect(wrapper).toMatchSnapshot(); - wrapper.find('Select').prop('onChange')({ value: 7 }); + wrapper.find('Select').prop('onChange')({ value: 7 }); wrapper.update(); expect(wrapper).toMatchSnapshot(); }); -it('returns new worker count', () => { +it('returns new worker count', async () => { const onClose = jest.fn(); const wrapper = shallow(); - // $FlowFixMe - wrapper.instance().mounted = true; - wrapper.find('Select').prop('onChange')({ value: 7 }); + (wrapper.instance() as WorkersForm).mounted = true; + wrapper.find('Select').prop('onChange')({ value: 7 }); wrapper.update(); submit(wrapper.find('form')); - return doAsync(() => { - expect(onClose).toBeCalled(); - }); + await new Promise(setImmediate); + expect(onClose).toBeCalled(); }); diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/Workers-test.js.snap b/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/Workers-test.tsx.snap similarity index 77% rename from server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/Workers-test.js.snap rename to server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/Workers-test.tsx.snap index 0a54eb44972..d9d6b6fe2f2 100644 --- a/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/Workers-test.js.snap +++ b/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/Workers-test.tsx.snap @@ -78,12 +78,30 @@ exports[`renders 2`] = ` exports[`renders 3`] = `
+ + + background_tasks.number_of_workers - 1 + 2 + + +
`; @@ -103,6 +121,26 @@ exports[`renders 4`] = ` > 2 + + + + + } + position="bottomright" + togglePopup={[Function]} + /> + `; diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/WorkersForm-test.js.snap b/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/WorkersForm-test.tsx.snap similarity index 91% rename from server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/WorkersForm-test.js.snap rename to server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/WorkersForm-test.tsx.snap index 4bf13d5848f..8ff615ea5e0 100644 --- a/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/WorkersForm-test.js.snap +++ b/server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/WorkersForm-test.tsx.snap @@ -62,43 +62,43 @@ exports[`changes select 1`] = ` options={ Array [ Object { - "label": 1, + "label": "1", "value": 1, }, Object { - "label": 2, + "label": "2", "value": 2, }, Object { - "label": 3, + "label": "3", "value": 3, }, Object { - "label": 4, + "label": "4", "value": 4, }, Object { - "label": 5, + "label": "5", "value": 5, }, Object { - "label": 6, + "label": "6", "value": 6, }, Object { - "label": 7, + "label": "7", "value": 7, }, Object { - "label": 8, + "label": "8", "value": 8, }, Object { - "label": 9, + "label": "9", "value": 9, }, Object { - "label": 10, + "label": "10", "value": 10, }, ] @@ -205,43 +205,43 @@ exports[`changes select 2`] = ` options={ Array [ Object { - "label": 1, + "label": "1", "value": 1, }, Object { - "label": 2, + "label": "2", "value": 2, }, Object { - "label": 3, + "label": "3", "value": 3, }, Object { - "label": 4, + "label": "4", "value": 4, }, Object { - "label": 5, + "label": "5", "value": 5, }, Object { - "label": 6, + "label": "6", "value": 6, }, Object { - "label": 7, + "label": "7", "value": 7, }, Object { - "label": 8, + "label": "8", "value": 8, }, Object { - "label": 9, + "label": "9", "value": 9, }, Object { - "label": 10, + "label": "10", "value": 10, }, ] diff --git a/server/sonar-web/src/main/less/components/bubble-popup.less b/server/sonar-web/src/main/less/components/bubble-popup.less index 25c7072b530..04dd6fb7d93 100644 --- a/server/sonar-web/src/main/less/components/bubble-popup.less +++ b/server/sonar-web/src/main/less/components/bubble-popup.less @@ -90,13 +90,11 @@ .bubble-popup-bottom-right { .bubble-popup-bottom; margin-left: 0; - margin-right: -@popupArrowSize; + margin-right: -16px; .bubble-popup-arrow { left: auto; right: 15px; - border-right-width: 0; - border-left-color: barBorderColor; } } diff --git a/sonar-core/src/main/resources/org/sonar/l10n/core.properties b/sonar-core/src/main/resources/org/sonar/l10n/core.properties index 0e3f376dfb6..ecd566e2aa7 100644 --- a/sonar-core/src/main/resources/org/sonar/l10n/core.properties +++ b/sonar-core/src/main/resources/org/sonar/l10n/core.properties @@ -76,6 +76,7 @@ issues=Issues inheritance=Inheritance key=Key language=Language +learn_more=Learn More library=Library line_number=Line Number links=Links @@ -2211,7 +2212,8 @@ background_tasks.number_of_workers=Number of Workers: background_tasks.number_of_workers.warning=Configuring additional workers without first vertically scaling your server could have negative performance impacts. background_tasks.change_number_of_workers=Edit CE Workers background_tasks.change_number_of_workers.hint=If your queue backs up behind the analysis reports from large projects, increasing the number of Compute Engine workers will allow you to take full advantage of having configured increased Compute Engine memory on a multi-core server (vertical scaling). -background_tasks.add_more_with_governance=Add more with Governance +background_tasks.add_more_workers=Speed up your analysis by adding more Workers +background_tasks.add_more_workers.text=Increase the number of Compute Engine Workers with the Governance product. Available in our commercial editions. background_tasks.search_by_task_or_component=Search by Task or Component background_tasks.failing_count=Count of projects where processing of most recent analysis report failed @@ -2580,7 +2582,6 @@ branches.set_leak_period=Set Leak Period branches.last_analysis_date=Last Analysis Date branches.no_support.header=Get the most out of SonarQube with branches analysis branches.no_support.header.text=Analyze each branch of your project separately with our Developer Pack. -branches.learn_more=Learn More branches.buy_developer_pack=Buy Developer Pack -- 2.39.5