diff options
author | Pascal Mugnier <pascal.mugnier@sonarsource.com> | 2018-03-08 11:14:02 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-03-08 11:14:02 +0100 |
commit | 5bafba36f7cfadcfe035153d33b3fdf495d62811 (patch) | |
tree | 53e76f73b02f912286f83e71159744c3fb8f6ed8 /server/sonar-web | |
parent | 115d4dae736d0f0c31675de7c0d8286db02a4798 (diff) | |
download | sonarqube-5bafba36f7cfadcfe035153d33b3fdf495d62811.tar.gz sonarqube-5bafba36f7cfadcfe035153d33b3fdf495d62811.zip |
SONAR-10476 Add a checkbox on top of issues list to allow global selection/unselection (#3131)
Diffstat (limited to 'server/sonar-web')
-rw-r--r-- | server/sonar-web/src/main/js/apps/issues/components/App.js | 24 | ||||
-rw-r--r-- | server/sonar-web/src/main/js/apps/issues/components/__tests__/App-test.js | 28 |
2 files changed, 50 insertions, 2 deletions
diff --git a/server/sonar-web/src/main/js/apps/issues/components/App.js b/server/sonar-web/src/main/js/apps/issues/components/App.js index 02c1a0e1e47..2c7181ff027 100644 --- a/server/sonar-web/src/main/js/apps/issues/components/App.js +++ b/server/sonar-web/src/main/js/apps/issues/components/App.js @@ -62,6 +62,7 @@ import ScreenPositionHelper from '../../../components/common/ScreenPositionHelpe import { getBranchName, isShortLivingBranch } from '../../../helpers/branches'; import { translate, translateWithParameters } from '../../../helpers/l10n'; import { scrollToElement } from '../../../helpers/scrolling'; +import Checkbox from '../../../components/controls/Checkbox'; /*:: import type { Issue } from '../../../components/issue/types'; */ /*:: import type { RawQuery } from '../../../helpers/query'; */ import '../styles.css'; @@ -741,9 +742,21 @@ export default class App extends React.PureComponent { selectNextFlow = () => this.setState(actions.selectNextFlow); selectPreviousFlow = () => this.setState(actions.selectPreviousFlow); + onCheckAll = (checked /*: boolean */) => { + if (checked) { + this.setState(state => ({ checked: state.issues.map(issue => issue.key) })); + } else { + this.setState(state => ({ checked: [] })); + } + }; + renderBulkChange(openIssue /*: ?Issue */) { const { component, currentUser } = this.props; - const { bulkChange, checked, paging } = this.state; + const { bulkChange, checked, paging, issues } = this.state; + + const isAllChecked = checked.length > 0 && issues.length === checked.length; + const thirdState = checked.length > 0 && !isAllChecked; + const isChecked = isAllChecked || thirdState; if (!currentUser.isLoggedIn || openIssue != null) { return null; @@ -751,8 +764,15 @@ export default class App extends React.PureComponent { return ( <div className="pull-left"> + <Checkbox + checked={isChecked} + className="spacer-right vertical-middle" + id="issues-selection" + onCheck={this.onCheckAll} + thirdState={thirdState} + /> {checked.length > 0 ? ( - <div className="dropdown"> + <div className="dropdown display-inline-block"> <button id="issues-bulk-change" data-toggle="dropdown"> {translate('bulk_change')} <i className="icon-dropdown little-spacer-left" /> diff --git a/server/sonar-web/src/main/js/apps/issues/components/__tests__/App-test.js b/server/sonar-web/src/main/js/apps/issues/components/__tests__/App-test.js index 7cf87139121..dfc109dcb2b 100644 --- a/server/sonar-web/src/main/js/apps/issues/components/__tests__/App-test.js +++ b/server/sonar-web/src/main/js/apps/issues/components/__tests__/App-test.js @@ -92,3 +92,31 @@ it('should avoid non-existing keys', async () => { wrapper.instance().handleIssueCheck('non-existing-key', eventWithShiftKey); expect(wrapper.state().checked.length).toBe(1); }); + +it('should be able to uncheck all issue with global checkbox', async () => { + const wrapper = shallowWithIntl(<App {...PROPS} />, { + context: { router: { replace } } + }); + + await waitAndUpdate(wrapper); + expect(wrapper.state().issues.length).toBe(4); + + wrapper.instance().handleIssueCheck('foo', eventNoShiftKey); + wrapper.instance().handleIssueCheck('bar', eventNoShiftKey); + expect(wrapper.state().checked.length).toBe(2); + + wrapper.instance().onCheckAll(false); + expect(wrapper.state().checked.length).toBe(0); +}); + +it('should be able to check all issue with global checkbox', async () => { + const wrapper = shallowWithIntl(<App {...PROPS} />, { + context: { router: { replace } } + }); + + await waitAndUpdate(wrapper); + + expect(wrapper.state().checked.length).toBe(0); + wrapper.instance().onCheckAll(true); + expect(wrapper.state().checked.length).toBe(wrapper.state().issues.length); +}); |