aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/src/main/js/components/issue
diff options
context:
space:
mode:
authorStas Vilchik <stas.vilchik@sonarsource.com>2018-05-09 09:17:16 +0200
committerSonarTech <sonartech@sonarsource.com>2018-05-09 20:20:46 +0200
commit09b3d167fa8f399e18a37d56e7c8cbb61f68f97f (patch)
tree415072b29720bdd0c5293a898eb4ed10b807859e /server/sonar-web/src/main/js/components/issue
parent302775229e9cc6debd58804446cb98c2ea563bd4 (diff)
downloadsonarqube-09b3d167fa8f399e18a37d56e7c8cbb61f68f97f.tar.gz
sonarqube-09b3d167fa8f399e18a37d56e7c8cbb61f68f97f.zip
SONAR-10664 Improve dropdown UI/UX consistency (#217)
Diffstat (limited to 'server/sonar-web/src/main/js/components/issue')
-rw-r--r--server/sonar-web/src/main/js/components/issue/IssueView.js20
-rw-r--r--server/sonar-web/src/main/js/components/issue/components/IssueAssign.js48
-rw-r--r--server/sonar-web/src/main/js/components/issue/components/IssueChangelog.js51
-rw-r--r--server/sonar-web/src/main/js/components/issue/components/IssueCommentAction.js31
-rw-r--r--server/sonar-web/src/main/js/components/issue/components/IssueCommentLine.js84
-rw-r--r--server/sonar-web/src/main/js/components/issue/components/IssueMessage.js1
-rw-r--r--server/sonar-web/src/main/js/components/issue/components/IssueSeverity.js41
-rw-r--r--server/sonar-web/src/main/js/components/issue/components/IssueTags.js52
-rw-r--r--server/sonar-web/src/main/js/components/issue/components/IssueTitleBar.js10
-rw-r--r--server/sonar-web/src/main/js/components/issue/components/IssueTransition.js49
-rw-r--r--server/sonar-web/src/main/js/components/issue/components/IssueType.js40
-rw-r--r--server/sonar-web/src/main/js/components/issue/components/SimilarIssuesFilter.js34
-rw-r--r--server/sonar-web/src/main/js/components/issue/components/__tests__/IssueAssign-test.js8
-rw-r--r--server/sonar-web/src/main/js/components/issue/components/__tests__/IssueChangelog-test.js2
-rw-r--r--server/sonar-web/src/main/js/components/issue/components/__tests__/IssueCommentAction-test.js6
-rw-r--r--server/sonar-web/src/main/js/components/issue/components/__tests__/IssueCommentLine-test.js4
-rw-r--r--server/sonar-web/src/main/js/components/issue/components/__tests__/IssueSeverity-test.js2
-rw-r--r--server/sonar-web/src/main/js/components/issue/components/__tests__/IssueTags-test.js2
-rw-r--r--server/sonar-web/src/main/js/components/issue/components/__tests__/IssueTransition-test.js2
-rw-r--r--server/sonar-web/src/main/js/components/issue/components/__tests__/IssueType-test.js2
-rw-r--r--server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueAssign-test.js.snap183
-rw-r--r--server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueChangelog-test.js.snap142
-rw-r--r--server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueCommentAction-test.js.snap42
-rw-r--r--server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueCommentLine-test.js.snap203
-rw-r--r--server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueSeverity-test.js.snap121
-rw-r--r--server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueTags-test.js.snap137
-rw-r--r--server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueTitleBar-test.js.snap2
-rw-r--r--server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueTransition-test.js.snap190
-rw-r--r--server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueType-test.js.snap125
-rw-r--r--server/sonar-web/src/main/js/components/issue/popups/ChangelogPopup.js10
-rw-r--r--server/sonar-web/src/main/js/components/issue/popups/CommentDeletePopup.js13
-rw-r--r--server/sonar-web/src/main/js/components/issue/popups/CommentPopup.js64
-rw-r--r--server/sonar-web/src/main/js/components/issue/popups/SetAssigneePopup.js10
-rw-r--r--server/sonar-web/src/main/js/components/issue/popups/SetIssueTagsPopup.tsx23
-rw-r--r--server/sonar-web/src/main/js/components/issue/popups/SetSeverityPopup.js13
-rw-r--r--server/sonar-web/src/main/js/components/issue/popups/SetTransitionPopup.js13
-rw-r--r--server/sonar-web/src/main/js/components/issue/popups/SetTypePopup.js13
-rw-r--r--server/sonar-web/src/main/js/components/issue/popups/SimilarIssuesPopup.js11
-rw-r--r--server/sonar-web/src/main/js/components/issue/popups/__tests__/CommentDeletePopup-test.js2
-rw-r--r--server/sonar-web/src/main/js/components/issue/popups/__tests__/CommentPopup-test.js18
-rw-r--r--server/sonar-web/src/main/js/components/issue/popups/__tests__/SetIssueTagsPopup-test.tsx7
-rw-r--r--server/sonar-web/src/main/js/components/issue/popups/__tests__/__snapshots__/ChangelogPopup-test.js.snap8
-rw-r--r--server/sonar-web/src/main/js/components/issue/popups/__tests__/__snapshots__/CommentDeletePopup-test.js.snap12
-rw-r--r--server/sonar-web/src/main/js/components/issue/popups/__tests__/__snapshots__/CommentPopup-test.js.snap138
-rw-r--r--server/sonar-web/src/main/js/components/issue/popups/__tests__/__snapshots__/SetIssueTagsPopup-test.tsx.snap39
-rw-r--r--server/sonar-web/src/main/js/components/issue/popups/__tests__/__snapshots__/SetSeverityPopup-test.js.snap6
-rw-r--r--server/sonar-web/src/main/js/components/issue/popups/__tests__/__snapshots__/SetTransitionPopup-test.js.snap6
-rw-r--r--server/sonar-web/src/main/js/components/issue/popups/__tests__/__snapshots__/SetTypePopup-test.js.snap6
48 files changed, 1017 insertions, 1029 deletions
diff --git a/server/sonar-web/src/main/js/components/issue/IssueView.js b/server/sonar-web/src/main/js/components/issue/IssueView.js
index 5f814a5347e..0598c4f9f07 100644
--- a/server/sonar-web/src/main/js/components/issue/IssueView.js
+++ b/server/sonar-web/src/main/js/components/issue/IssueView.js
@@ -51,15 +51,14 @@ export default class IssueView extends React.PureComponent {
handleCheck = (event /*: Event */) => {
event.preventDefault();
- event.stopPropagation();
if (this.props.onCheck) {
this.props.onCheck(this.props.issue.key, event);
}
};
handleClick = (event /*: Event & { target: HTMLElement } */) => {
- event.preventDefault();
- if (this.props.onClick) {
+ if (!isClickable(event.target) && this.props.onClick) {
+ event.preventDefault();
this.props.onClick(this.props.issue.key);
}
};
@@ -100,12 +99,12 @@ export default class IssueView extends React.PureComponent {
togglePopup={this.props.togglePopup}
/>
<IssueActionsBar
- issue={issue}
currentPopup={this.props.currentPopup}
+ issue={issue}
onAssign={this.props.onAssign}
+ onChange={this.props.onChange}
onFail={this.props.onFail}
togglePopup={this.props.togglePopup}
- onChange={this.props.onChange}
/>
{issue.comments &&
issue.comments.length > 0 && (
@@ -114,8 +113,8 @@ export default class IssueView extends React.PureComponent {
<IssueCommentLine
comment={comment}
key={comment.key}
- onEdit={this.editComment}
onDelete={this.deleteComment}
+ onEdit={this.editComment}
/>
))}
</div>
@@ -137,3 +136,12 @@ export default class IssueView extends React.PureComponent {
);
}
}
+
+function isClickable(node /*: any */) {
+ if (!node) {
+ return false;
+ }
+ const clickableTags = ['A', 'BUTTON', 'INPUT', 'TEXTAREA'];
+ const tagName = (node.tagName || '').toUpperCase();
+ return clickableTags.includes(tagName) || isClickable(node.parentNode);
+}
diff --git a/server/sonar-web/src/main/js/components/issue/components/IssueAssign.js b/server/sonar-web/src/main/js/components/issue/components/IssueAssign.js
index 3f7d5e84ac7..783fdec65b0 100644
--- a/server/sonar-web/src/main/js/components/issue/components/IssueAssign.js
+++ b/server/sonar-web/src/main/js/components/issue/components/IssueAssign.js
@@ -19,9 +19,11 @@
*/
// @flow
import React from 'react';
-import Avatar from '../../../components/ui/Avatar';
-import BubblePopupHelper from '../../../components/common/BubblePopupHelper';
import SetAssigneePopup from '../popups/SetAssigneePopup';
+import Avatar from '../../../components/ui/Avatar';
+import Toggler from '../../../components/controls/Toggler';
+import DropdownIcon from '../../../components/icons-components/DropdownIcon';
+import { Button } from '../../../components/ui/buttons';
import { translate } from '../../../helpers/l10n';
/*:: import type { Issue } from '../types'; */
@@ -43,6 +45,10 @@ export default class IssueAssign extends React.PureComponent {
this.props.togglePopup('assign', open);
};
+ handleClose = () => {
+ this.toggleAssign(false);
+ };
+
renderAssignee() {
const { issue } = this.props;
return (
@@ -67,24 +73,26 @@ export default class IssueAssign extends React.PureComponent {
render() {
if (this.props.canAssign) {
return (
- <BubblePopupHelper
- isOpen={this.props.isOpen && this.props.canAssign}
- position="bottomleft"
- togglePopup={this.toggleAssign}
- popup={
- <SetAssigneePopup
- issue={this.props.issue}
- onFail={this.props.onFail}
- onSelect={this.props.onAssign}
- />
- }>
- <button
- className="button-link issue-action issue-action-with-options js-issue-assign"
- onClick={this.toggleAssign}>
- {this.renderAssignee()}
- <i className="little-spacer-left icon-dropdown" />
- </button>
- </BubblePopupHelper>
+ <div className="dropdown">
+ <Toggler
+ closeOnEscape={true}
+ onRequestClose={this.handleClose}
+ open={this.props.isOpen && this.props.canAssign}
+ overlay={
+ <SetAssigneePopup
+ issue={this.props.issue}
+ onFail={this.props.onFail}
+ onSelect={this.props.onAssign}
+ />
+ }>
+ <Button
+ className="button-link issue-action issue-action-with-options js-issue-assign"
+ onClick={this.toggleAssign}>
+ {this.renderAssignee()}
+ <DropdownIcon className="little-spacer-left" />
+ </Button>
+ </Toggler>
+ </div>
);
} else {
return this.renderAssignee();
diff --git a/server/sonar-web/src/main/js/components/issue/components/IssueChangelog.js b/server/sonar-web/src/main/js/components/issue/components/IssueChangelog.js
index 43f5adc2d91..a70f6ca5a33 100644
--- a/server/sonar-web/src/main/js/components/issue/components/IssueChangelog.js
+++ b/server/sonar-web/src/main/js/components/issue/components/IssueChangelog.js
@@ -19,11 +19,12 @@
*/
// @flow
import React from 'react';
-import BubblePopupHelper from '../../../components/common/BubblePopupHelper';
import ChangelogPopup from '../popups/ChangelogPopup';
import DateFromNow from '../../../components/intl/DateFromNow';
import DateTimeFormatter from '../../../components/intl/DateTimeFormatter';
+import Toggler from '../../../components/controls/Toggler';
import Tooltip from '../../../components/controls/Tooltip';
+import { Button } from '../../../components/ui/buttons';
/*:: import type { Issue } from '../types'; */
/*::
@@ -39,35 +40,39 @@ type Props = {
export default class IssueChangelog extends React.PureComponent {
/*:: props: Props; */
- handleClick = (evt /*: SyntheticInputEvent */) => {
- evt.preventDefault();
+ toggleChangelog = (open /*: boolean | void */) => {
+ this.props.togglePopup('changelog', open);
+ };
+
+ handleClick = () => {
this.toggleChangelog();
};
- toggleChangelog = (open /*: boolean | void */) => {
- this.props.togglePopup('changelog', open);
+ handleClose = () => {
+ this.toggleChangelog(false);
};
render() {
return (
- <BubblePopupHelper
- isOpen={this.props.isOpen}
- position="bottomright"
- togglePopup={this.toggleChangelog}
- popup={<ChangelogPopup issue={this.props.issue} onFail={this.props.onFail} />}>
- <Tooltip
- mouseEnterDelay={0.5}
- overlay={<DateTimeFormatter date={this.props.creationDate} />}>
- <button
- className="button-link issue-action issue-action-with-options js-issue-show-changelog"
- onClick={this.handleClick}>
- <span className="issue-meta-label">
- <DateFromNow date={this.props.creationDate} />
- </span>
- <i className="icon-dropdown little-spacer-left" />
- </button>
- </Tooltip>
- </BubblePopupHelper>
+ <div className="dropdown">
+ <Toggler
+ onRequestClose={this.handleClose}
+ open={this.props.isOpen}
+ overlay={<ChangelogPopup issue={this.props.issue} onFail={this.props.onFail} />}>
+ <Tooltip
+ mouseEnterDelay={0.5}
+ overlay={<DateTimeFormatter date={this.props.creationDate} />}>
+ <Button
+ className="button-link issue-action issue-action-with-options js-issue-show-changelog"
+ onClick={this.handleClick}>
+ <span className="issue-meta-label">
+ <DateFromNow date={this.props.creationDate} />
+ </span>
+ <i className="icon-dropdown little-spacer-left" />
+ </Button>
+ </Tooltip>
+ </Toggler>
+ </div>
);
}
}
diff --git a/server/sonar-web/src/main/js/components/issue/components/IssueCommentAction.js b/server/sonar-web/src/main/js/components/issue/components/IssueCommentAction.js
index 01ba1f984a1..814d4053cf4 100644
--- a/server/sonar-web/src/main/js/components/issue/components/IssueCommentAction.js
+++ b/server/sonar-web/src/main/js/components/issue/components/IssueCommentAction.js
@@ -20,7 +20,8 @@
// @flow
import React from 'react';
import { updateIssue } from '../actions';
-import BubblePopupHelper from '../../../components/common/BubblePopupHelper';
+import Toggler from '../../../components/controls/Toggler';
+import { Button } from '../../../components/ui/buttons';
import CommentPopup from '../popups/CommentPopup';
import { addIssueComment } from '../../../api/issues';
import { translate } from '../../../helpers/l10n';
@@ -49,29 +50,33 @@ export default class IssueCommentAction extends React.PureComponent {
this.props.toggleComment(false);
};
- handleCommentClick = () => this.props.toggleComment();
+ handleCommentClick = () => {
+ this.props.toggleComment();
+ };
+
+ handleClose = () => {
+ this.props.toggleComment(false);
+ };
render() {
return (
- <li className="issue-meta">
- <BubblePopupHelper
- isOpen={this.props.currentPopup === 'comment'}
- position="bottomleft"
- togglePopup={this.props.toggleComment}
- popup={
+ <li className="issue-meta dropdown">
+ <Toggler
+ onRequestClose={this.handleClose}
+ open={this.props.currentPopup === 'comment'}
+ overlay={
<CommentPopup
- customClass="issue-comment-bubble-popup"
- placeholder={this.props.commentPlaceholder}
onComment={this.addComment}
+ placeholder={this.props.commentPlaceholder}
toggleComment={this.props.toggleComment}
/>
}>
- <button
+ <Button
className="button-link issue-action js-issue-comment"
onClick={this.handleCommentClick}>
<span className="issue-meta-label">{translate('issue.comment.formlink')}</span>
- </button>
- </BubblePopupHelper>
+ </Button>
+ </Toggler>
</li>
);
}
diff --git a/server/sonar-web/src/main/js/components/issue/components/IssueCommentLine.js b/server/sonar-web/src/main/js/components/issue/components/IssueCommentLine.js
index 1773bd16a0c..3a0910f6552 100644
--- a/server/sonar-web/src/main/js/components/issue/components/IssueCommentLine.js
+++ b/server/sonar-web/src/main/js/components/issue/components/IssueCommentLine.js
@@ -20,7 +20,7 @@
// @flow
import React from 'react';
import Avatar from '../../../components/ui/Avatar';
-import BubblePopupHelper from '../../../components/common/BubblePopupHelper';
+import Toggler from '../../../components/controls/Toggler';
import EditIcon from '../../../components/icons-components/EditIcon';
import { EditButton, DeleteButton } from '../../../components/ui/buttons';
import CommentDeletePopup from '../popups/CommentDeletePopup';
@@ -48,12 +48,6 @@ export default class IssueCommentLine extends React.PureComponent {
openPopup: ''
};
- handleCommentClick = (event /*: Event & {target: HTMLElement}*/) => {
- if (event.target.tagName === 'A') {
- event.stopPropagation();
- }
- };
-
handleEdit = (text /*: string */) => {
this.props.onEdit(this.props.comment.key, text);
this.toggleEditPopup(false);
@@ -75,9 +69,17 @@ export default class IssueCommentLine extends React.PureComponent {
});
};
- toggleDeletePopup = (force /*: ?boolean */) => this.togglePopup('delete', force);
+ toggleDeletePopup = (force /*: ?boolean */) => {
+ this.togglePopup('delete', force);
+ };
- toggleEditPopup = (force /*: ?boolean */) => this.togglePopup('edit', force);
+ toggleEditPopup = (force /*: ?boolean */) => {
+ this.togglePopup('edit', force);
+ };
+
+ closePopups = () => {
+ this.setState({ openPopup: '' });
+ };
render() {
const { comment } = this.props;
@@ -95,49 +97,45 @@ export default class IssueCommentLine extends React.PureComponent {
<div
className="issue-comment-text markdown"
dangerouslySetInnerHTML={{ __html: comment.htmlText }}
- onClick={this.handleCommentClick}
- role="Listitem"
- tabIndex={0}
/>
<div className="issue-comment-age">
<DateFromNow date={comment.createdAt} />
</div>
<div className="issue-comment-actions">
{comment.updatable && (
- <BubblePopupHelper
- className="bubble-popup-helper-inline"
- isOpen={this.state.openPopup === 'edit'}
- offset={{ vertical: 0, horizontal: -6 }}
- position="bottomright"
- togglePopup={this.toggleDeletePopup}
- popup={
- <CommentPopup
- comment={comment}
- customClass="issue-edit-comment-bubble-popup"
- onComment={this.handleEdit}
- placeholder=""
- toggleComment={this.toggleEditPopup}
+ <div className="dropdown">
+ <Toggler
+ className="display-inline-block"
+ onRequestClose={this.closePopups}
+ open={this.state.openPopup === 'edit'}
+ overlay={
+ <CommentPopup
+ comment={comment}
+ onComment={this.handleEdit}
+ placeholder=""
+ toggleComment={this.toggleEditPopup}
+ />
+ }>
+ <EditButton
+ className="js-issue-comment-edit button-small"
+ onClick={this.toggleEditPopup}
/>
- }>
- <EditButton
- className="js-issue-comment-edit button-small"
- onClick={this.toggleEditPopup}
- />
- </BubblePopupHelper>
+ </Toggler>
+ </div>
)}
{comment.updatable && (
- <BubblePopupHelper
- className="bubble-popup-helper-inline"
- isOpen={this.state.openPopup === 'delete'}
- offset={{ vertical: 0, horizontal: -10 }}
- position="bottomright"
- togglePopup={this.toggleDeletePopup}
- popup={<CommentDeletePopup onDelete={this.handleDelete} />}>
- <DeleteButton
- className="js-issue-comment-delete button-small"
- onClick={this.toggleDeletePopup}
- />
- </BubblePopupHelper>
+ <div className="dropdown">
+ <Toggler
+ className="display-inline-block"
+ onRequestClose={this.closePopups}
+ open={this.state.openPopup === 'delete'}
+ overlay={<CommentDeletePopup onDelete={this.handleDelete} />}>
+ <DeleteButton
+ className="js-issue-comment-delete button-small"
+ onClick={this.toggleDeletePopup}
+ />
+ </Toggler>
+ </div>
)}
</div>
</div>
diff --git a/server/sonar-web/src/main/js/components/issue/components/IssueMessage.js b/server/sonar-web/src/main/js/components/issue/components/IssueMessage.js
index 888d7f2d521..1f8a9cb2ae5 100644
--- a/server/sonar-web/src/main/js/components/issue/components/IssueMessage.js
+++ b/server/sonar-web/src/main/js/components/issue/components/IssueMessage.js
@@ -38,7 +38,6 @@ export default class IssueMessage extends React.PureComponent {
handleClick = (e /*: MouseEvent */) => {
e.preventDefault();
- e.stopPropagation();
this.context.workspace.openRule({
key: this.props.rule,
organization: this.props.organization
diff --git a/server/sonar-web/src/main/js/components/issue/components/IssueSeverity.js b/server/sonar-web/src/main/js/components/issue/components/IssueSeverity.js
index 326e64e64ab..f75e0e8f3c7 100644
--- a/server/sonar-web/src/main/js/components/issue/components/IssueSeverity.js
+++ b/server/sonar-web/src/main/js/components/issue/components/IssueSeverity.js
@@ -19,10 +19,12 @@
*/
// @flow
import React from 'react';
-import BubblePopupHelper from '../../../components/common/BubblePopupHelper';
import SetSeverityPopup from '../popups/SetSeverityPopup';
-import SeverityHelper from '../../../components/shared/SeverityHelper';
import { setIssueSeverity } from '../../../api/issues';
+import Toggler from '../../../components/controls/Toggler';
+import DropdownIcon from '../../../components/icons-components/DropdownIcon';
+import SeverityHelper from '../../../components/shared/SeverityHelper';
+import { Button } from '../../../components/ui/buttons';
/*:: import type { Issue } from '../types'; */
/*::
@@ -42,28 +44,31 @@ export default class IssueSeverity extends React.PureComponent {
this.props.togglePopup('set-severity', open);
};
- setSeverity = (severity /*: string */) =>
+ setSeverity = (severity /*: string */) => {
this.props.setIssueProperty('severity', 'set-severity', setIssueSeverity, severity);
+ };
+
+ handleClose = () => {
+ this.toggleSetSeverity(false);
+ };
render() {
const { issue } = this.props;
if (this.props.canSetSeverity) {
return (
- <BubblePopupHelper
- isOpen={this.props.isOpen && this.props.canSetSeverity}
- position="bottomleft"
- togglePopup={this.toggleSetSeverity}
- popup={<SetSeverityPopup issue={issue} onSelect={this.setSeverity} />}>
- <button
- className="button-link issue-action issue-action-with-options js-issue-set-severity"
- onClick={this.toggleSetSeverity}>
- <SeverityHelper
- className="issue-meta-label little-spacer-right"
- severity={issue.severity}
- />
- <i className="little-spacer-left icon-dropdown" />
- </button>
- </BubblePopupHelper>
+ <div className="dropdown">
+ <Toggler
+ onRequestClose={this.handleClose}
+ open={this.props.isOpen && this.props.canSetSeverity}
+ overlay={<SetSeverityPopup issue={issue} onSelect={this.setSeverity} />}>
+ <Button
+ className="button-link issue-action issue-action-with-options js-issue-set-severity"
+ onClick={this.toggleSetSeverity}>
+ <SeverityHelper className="issue-meta-label" severity={issue.severity} />
+ <DropdownIcon className="little-spacer-left" />
+ </Button>
+ </Toggler>
+ </div>
);
} else {
return <SeverityHelper className="issue-meta-label" severity={issue.severity} />;
diff --git a/server/sonar-web/src/main/js/components/issue/components/IssueTags.js b/server/sonar-web/src/main/js/components/issue/components/IssueTags.js
index fb183a7f8b7..b9f1fcba0be 100644
--- a/server/sonar-web/src/main/js/components/issue/components/IssueTags.js
+++ b/server/sonar-web/src/main/js/components/issue/components/IssueTags.js
@@ -20,10 +20,11 @@
// @flow
import React from 'react';
import { updateIssue } from '../actions';
-import BubblePopupHelper from '../../../components/common/BubblePopupHelper';
import SetIssueTagsPopup from '../popups/SetIssueTagsPopup';
-import TagsList from '../../../components/tags/TagsList';
import { setIssueTags } from '../../../api/issues';
+import Toggler from '../../../components/controls/Toggler';
+import TagsList from '../../../components/tags/TagsList';
+import { Button } from '../../../components/ui/buttons';
import { translate } from '../../../helpers/l10n';
/*:: import type { Issue } from '../types'; */
@@ -57,32 +58,39 @@ export default class IssueTags extends React.PureComponent {
);
};
+ handleClose = () => {
+ this.toggleSetTags(false);
+ };
+
render() {
const { issue } = this.props;
const { tags = [] } = issue;
if (this.props.canSetTags) {
return (
- <BubblePopupHelper
- isOpen={this.props.isOpen}
- popup={
- <SetIssueTagsPopup
- organization={issue.projectOrganization}
- selectedTags={tags}
- setTags={this.setTags}
- />
- }
- position="bottomright"
- togglePopup={this.toggleSetTags}>
- <button
- className={'js-issue-edit-tags button-link issue-action issue-action-with-options'}
- onClick={this.toggleSetTags}>
- <TagsList
- allowUpdate={this.props.canSetTags}
- tags={issue.tags && issue.tags.length > 0 ? issue.tags : [translate('issue.no_tag')]}
- />
- </button>
- </BubblePopupHelper>
+ <div className="dropdown">
+ <Toggler
+ onRequestClose={this.handleClose}
+ open={this.props.isOpen}
+ overlay={
+ <SetIssueTagsPopup
+ organization={issue.projectOrganization}
+ selectedTags={tags}
+ setTags={this.setTags}
+ />
+ }>
+ <Button
+ className={'js-issue-edit-tags button-link issue-action issue-action-with-options'}
+ onClick={this.toggleSetTags}>
+ <TagsList
+ allowUpdate={this.props.canSetTags}
+ tags={
+ issue.tags && issue.tags.length > 0 ? issue.tags : [translate('issue.no_tag')]
+ }
+ />
+ </Button>
+ </Toggler>
+ </div>
);
} else {
return (
diff --git a/server/sonar-web/src/main/js/components/issue/components/IssueTitleBar.js b/server/sonar-web/src/main/js/components/issue/components/IssueTitleBar.js
index 0dad342b1b5..781eebd1f06 100644
--- a/server/sonar-web/src/main/js/components/issue/components/IssueTitleBar.js
+++ b/server/sonar-web/src/main/js/components/issue/components/IssueTitleBar.js
@@ -45,8 +45,6 @@ type Props = {|
|};
*/
-const stopPropagation = (event /*: Event */) => event.stopPropagation();
-
export default function IssueTitleBar(props /*: Props */) {
const { issue } = props;
const hasSimilarIssuesFilter = props.onFilter != null;
@@ -103,7 +101,7 @@ export default function IssueTitleBar(props /*: Props */) {
{displayLocations && (
<li className="issue-meta">
{props.displayLocationsLink ? (
- <Link onClick={stopPropagation} target="_blank" to={issueUrl}>
+ <Link target="_blank" to={issueUrl}>
{locationsBadge}
</Link>
) : (
@@ -112,11 +110,7 @@ export default function IssueTitleBar(props /*: Props */) {
</li>
)}
<li className="issue-meta">
- <Link
- className="js-issue-permalink link-no-underline"
- onClick={stopPropagation}
- target="_blank"
- to={issueUrl}>
+ <Link className="js-issue-permalink link-no-underline" target="_blank" to={issueUrl}>
<LinkIcon />
</Link>
</li>
diff --git a/server/sonar-web/src/main/js/components/issue/components/IssueTransition.js b/server/sonar-web/src/main/js/components/issue/components/IssueTransition.js
index 28379cde1cd..3aced6f8685 100644
--- a/server/sonar-web/src/main/js/components/issue/components/IssueTransition.js
+++ b/server/sonar-web/src/main/js/components/issue/components/IssueTransition.js
@@ -20,10 +20,12 @@
// @flow
import React from 'react';
import { updateIssue } from '../actions';
-import BubblePopupHelper from '../../../components/common/BubblePopupHelper';
import SetTransitionPopup from '../popups/SetTransitionPopup';
-import StatusHelper from '../../../components/shared/StatusHelper';
import { setIssueTransition } from '../../../api/issues';
+import Toggler from '../../../components/controls/Toggler';
+import DropdownIcon from '../../../components/icons-components/DropdownIcon';
+import StatusHelper from '../../../components/shared/StatusHelper';
+import { Button } from '../../../components/ui/buttons';
/*:: import type { Issue } from '../types'; */
/*::
@@ -53,36 +55,41 @@ export default class IssueTransition extends React.PureComponent {
this.props.togglePopup('transition', open);
};
+ handleClose = () => {
+ this.toggleSetTransition(false);
+ };
+
render() {
const { issue } = this.props;
if (this.props.hasTransitions) {
return (
- <BubblePopupHelper
- isOpen={this.props.isOpen && this.props.hasTransitions}
- position="bottomleft"
- togglePopup={this.toggleSetTransition}
- popup={
- <SetTransitionPopup transitions={issue.transitions} onSelect={this.setTransition} />
- }>
- <button
- className="button-link issue-action issue-action-with-options js-issue-transition"
- onClick={this.toggleSetTransition}>
- <StatusHelper
- className="issue-meta-label little-spacer-right"
- status={issue.status}
- resolution={issue.resolution}
- />
- <i className="little-spacer-left icon-dropdown" />
- </button>
- </BubblePopupHelper>
+ <div className="dropdown">
+ <Toggler
+ onRequestClose={this.handleClose}
+ open={this.props.isOpen && this.props.hasTransitions}
+ overlay={
+ <SetTransitionPopup onSelect={this.setTransition} transitions={issue.transitions} />
+ }>
+ <Button
+ className="button-link issue-action issue-action-with-options js-issue-transition"
+ onClick={this.toggleSetTransition}>
+ <StatusHelper
+ className="issue-meta-label"
+ resolution={issue.resolution}
+ status={issue.status}
+ />
+ <DropdownIcon className="little-spacer-left" />
+ </Button>
+ </Toggler>
+ </div>
);
} else {
return (
<StatusHelper
className="issue-meta-label"
- status={issue.status}
resolution={issue.resolution}
+ status={issue.status}
/>
);
}
diff --git a/server/sonar-web/src/main/js/components/issue/components/IssueType.js b/server/sonar-web/src/main/js/components/issue/components/IssueType.js
index 60941288e4b..380e8668a32 100644
--- a/server/sonar-web/src/main/js/components/issue/components/IssueType.js
+++ b/server/sonar-web/src/main/js/components/issue/components/IssueType.js
@@ -19,10 +19,12 @@
*/
// @flow
import React from 'react';
-import BubblePopupHelper from '../../../components/common/BubblePopupHelper';
-import IssueTypeIcon from '../../../components/ui/IssueTypeIcon';
import SetTypePopup from '../popups/SetTypePopup';
import { setIssueType } from '../../../api/issues';
+import Toggler from '../../../components/controls/Toggler';
+import DropdownIcon from '../../../components/icons-components/DropdownIcon';
+import { Button } from '../../../components/ui/buttons';
+import IssueTypeIcon from '../../../components/ui/IssueTypeIcon';
import { translate } from '../../../helpers/l10n';
/*:: import type { Issue } from '../types'; */
@@ -43,26 +45,32 @@ export default class IssueType extends React.PureComponent {
this.props.togglePopup('set-type', open);
};
- setType = (type /*: string */) =>
+ setType = (type /*: string */) => {
this.props.setIssueProperty('type', 'set-type', setIssueType, type);
+ };
+
+ handleClose = () => {
+ this.toggleSetType(false);
+ };
render() {
const { issue } = this.props;
if (this.props.canSetSeverity) {
return (
- <BubblePopupHelper
- isOpen={this.props.isOpen && this.props.canSetSeverity}
- position="bottomleft"
- togglePopup={this.toggleSetType}
- popup={<SetTypePopup issue={issue} onSelect={this.setType} />}>
- <button
- className="button-link issue-action issue-action-with-options js-issue-set-type"
- onClick={this.toggleSetType}>
- <IssueTypeIcon className="little-spacer-right" query={issue.type} />
- {translate('issue.type', issue.type)}
- <i className="little-spacer-left icon-dropdown" />
- </button>
- </BubblePopupHelper>
+ <div className="dropdown">
+ <Toggler
+ onRequestClose={this.handleClose}
+ open={this.props.isOpen && this.props.canSetSeverity}
+ overlay={<SetTypePopup issue={issue} onSelect={this.setType} />}>
+ <Button
+ className="button-link issue-action issue-action-with-options js-issue-set-type"
+ onClick={this.toggleSetType}>
+ <IssueTypeIcon className="little-spacer-right" query={issue.type} />
+ {translate('issue.type', issue.type)}
+ <DropdownIcon className="little-spacer-left" />
+ </Button>
+ </Toggler>
+ </div>
);
} else {
return (
diff --git a/server/sonar-web/src/main/js/components/issue/components/SimilarIssuesFilter.js b/server/sonar-web/src/main/js/components/issue/components/SimilarIssuesFilter.js
index b9da955025a..5b900ac2e48 100644
--- a/server/sonar-web/src/main/js/components/issue/components/SimilarIssuesFilter.js
+++ b/server/sonar-web/src/main/js/components/issue/components/SimilarIssuesFilter.js
@@ -19,8 +19,10 @@
*/
// @flow
import React from 'react';
-import BubblePopupHelper from '../../../components/common/BubblePopupHelper';
import SimilarIssuesPopup from '../popups/SimilarIssuesPopup';
+import Toggler from '../../../components/controls/Toggler';
+import DropdownIcon from '../../../components/icons-components/DropdownIcon';
+import { Button } from '../../../components/ui/buttons';
import { translate } from '../../../helpers/l10n';
/*:: import type { Issue } from '../types'; */
@@ -51,20 +53,26 @@ export default class SimilarIssuesFilter extends React.PureComponent {
this.props.togglePopup('similarIssues', open);
};
+ handleClose = () => {
+ this.togglePopup(false);
+ };
+
render() {
return (
- <BubblePopupHelper
- isOpen={this.props.isOpen}
- position="bottomright"
- togglePopup={this.togglePopup}
- popup={<SimilarIssuesPopup issue={this.props.issue} onFilter={this.handleFilter} />}>
- <button
- className="js-issue-filter button-link issue-action issue-action-with-options"
- aria-label={translate('issue.filter_similar_issues')}
- onClick={this.handleClick}>
- <i className="icon-filter icon-half-transparent" /> <i className="icon-dropdown" />
- </button>
- </BubblePopupHelper>
+ <div className="dropdown">
+ <Toggler
+ onRequestClose={this.handleClose}
+ open={this.props.isOpen}
+ overlay={<SimilarIssuesPopup issue={this.props.issue} onFilter={this.handleFilter} />}>
+ <Button
+ aria-label={translate('issue.filter_similar_issues')}
+ className="js-issue-filter button-link issue-action issue-action-with-options"
+ onClick={this.handleClick}>
+ <i className="icon-filter icon-half-transparent" />
+ <DropdownIcon className="little-spacer-left" />
+ </Button>
+ </Toggler>
+ </div>
);
}
}
diff --git a/server/sonar-web/src/main/js/components/issue/components/__tests__/IssueAssign-test.js b/server/sonar-web/src/main/js/components/issue/components/__tests__/IssueAssign-test.js
index cdd7cfeb6f1..ad39643695e 100644
--- a/server/sonar-web/src/main/js/components/issue/components/__tests__/IssueAssign-test.js
+++ b/server/sonar-web/src/main/js/components/issue/components/__tests__/IssueAssign-test.js
@@ -34,8 +34,8 @@ it('should render without the action when the correct rights are missing', () =>
canAssign={false}
isOpen={false}
issue={issue}
- onFail={jest.fn()}
onAssign={jest.fn()}
+ onFail={jest.fn()}
togglePopup={jest.fn()}
/>
);
@@ -48,8 +48,8 @@ it('should render with the action', () => {
canAssign={true}
isOpen={false}
issue={issue}
- onFail={jest.fn()}
onAssign={jest.fn()}
+ onFail={jest.fn()}
togglePopup={jest.fn()}
/>
);
@@ -63,12 +63,12 @@ it('should open the popup when the button is clicked', () => {
canAssign={true}
isOpen={false}
issue={issue}
- onFail={jest.fn()}
onAssign={jest.fn()}
+ onFail={jest.fn()}
togglePopup={toggle}
/>
);
- click(element.find('button'));
+ click(element.find('Button'));
expect(toggle.mock.calls).toMatchSnapshot();
element.setProps({ isOpen: true });
expect(element).toMatchSnapshot();
diff --git a/server/sonar-web/src/main/js/components/issue/components/__tests__/IssueChangelog-test.js b/server/sonar-web/src/main/js/components/issue/components/__tests__/IssueChangelog-test.js
index 0b2b9071cd8..8e03fdef42a 100644
--- a/server/sonar-web/src/main/js/components/issue/components/__tests__/IssueChangelog-test.js
+++ b/server/sonar-web/src/main/js/components/issue/components/__tests__/IssueChangelog-test.js
@@ -52,7 +52,7 @@ it('should open the popup when the button is clicked', () => {
togglePopup={toggle}
/>
);
- click(element.find('button'));
+ click(element.find('Button'));
expect(toggle.mock.calls).toMatchSnapshot();
element.setProps({ isOpen: true });
expect(element).toMatchSnapshot();
diff --git a/server/sonar-web/src/main/js/components/issue/components/__tests__/IssueCommentAction-test.js b/server/sonar-web/src/main/js/components/issue/components/__tests__/IssueCommentAction-test.js
index d54334a61f9..2114f366226 100644
--- a/server/sonar-web/src/main/js/components/issue/components/__tests__/IssueCommentAction-test.js
+++ b/server/sonar-web/src/main/js/components/issue/components/__tests__/IssueCommentAction-test.js
@@ -25,8 +25,8 @@ import { click } from '../../../../helpers/testUtils';
it('should render correctly', () => {
const element = shallow(
<IssueCommentAction
- issueKey="issue-key"
currentPopup={null}
+ issueKey="issue-key"
onFail={jest.fn()}
onIssueChange={jest.fn()}
toggleComment={jest.fn()}
@@ -39,14 +39,14 @@ it('should open the popup when the button is clicked', () => {
const toggle = jest.fn();
const element = shallow(
<IssueCommentAction
- issueKey="issue-key"
currentPopup={null}
+ issueKey="issue-key"
onFail={jest.fn()}
onIssueChange={jest.fn()}
toggleComment={toggle}
/>
);
- click(element.find('button'));
+ click(element.find('Button'));
expect(toggle.mock.calls.length).toBe(1);
element.setProps({ currentPopup: 'comment' });
expect(element).toMatchSnapshot();
diff --git a/server/sonar-web/src/main/js/components/issue/components/__tests__/IssueCommentLine-test.js b/server/sonar-web/src/main/js/components/issue/components/__tests__/IssueCommentLine-test.js
index a321192729a..90cc0e1d8dc 100644
--- a/server/sonar-web/src/main/js/components/issue/components/__tests__/IssueCommentLine-test.js
+++ b/server/sonar-web/src/main/js/components/issue/components/__tests__/IssueCommentLine-test.js
@@ -53,9 +53,9 @@ it('should open the right popups when the buttons are clicked', () => {
const element = shallow(
<IssueCommentLine comment={comment} onDelete={jest.fn()} onEdit={jest.fn()} />
);
- element.find('.js-issue-comment-edit').prop('onClick')();
+ click(element.find('.js-issue-comment-edit'));
expect(element.state()).toMatchSnapshot();
- element.find('.js-issue-comment-delete').prop('onClick')();
+ click(element.find('.js-issue-comment-delete'));
expect(element.state()).toMatchSnapshot();
element.update();
expect(element).toMatchSnapshot();
diff --git a/server/sonar-web/src/main/js/components/issue/components/__tests__/IssueSeverity-test.js b/server/sonar-web/src/main/js/components/issue/components/__tests__/IssueSeverity-test.js
index 98e4cf45c5b..08b00404347 100644
--- a/server/sonar-web/src/main/js/components/issue/components/__tests__/IssueSeverity-test.js
+++ b/server/sonar-web/src/main/js/components/issue/components/__tests__/IssueSeverity-test.js
@@ -63,7 +63,7 @@ it('should open the popup when the button is clicked', () => {
togglePopup={toggle}
/>
);
- click(element.find('button'));
+ click(element.find('Button'));
expect(toggle.mock.calls).toMatchSnapshot();
element.setProps({ isOpen: true });
expect(element).toMatchSnapshot();
diff --git a/server/sonar-web/src/main/js/components/issue/components/__tests__/IssueTags-test.js b/server/sonar-web/src/main/js/components/issue/components/__tests__/IssueTags-test.js
index aa353241a8a..81d9a512a45 100644
--- a/server/sonar-web/src/main/js/components/issue/components/__tests__/IssueTags-test.js
+++ b/server/sonar-web/src/main/js/components/issue/components/__tests__/IssueTags-test.js
@@ -71,7 +71,7 @@ it('should open the popup when the button is clicked', () => {
togglePopup={toggle}
/>
);
- click(element.find('button'));
+ click(element.find('Button'));
expect(toggle.mock.calls).toMatchSnapshot();
element.setProps({ isOpen: true });
expect(element).toMatchSnapshot();
diff --git a/server/sonar-web/src/main/js/components/issue/components/__tests__/IssueTransition-test.js b/server/sonar-web/src/main/js/components/issue/components/__tests__/IssueTransition-test.js
index 9bfc5d7cd85..98da66e0449 100644
--- a/server/sonar-web/src/main/js/components/issue/components/__tests__/IssueTransition-test.js
+++ b/server/sonar-web/src/main/js/components/issue/components/__tests__/IssueTransition-test.js
@@ -84,7 +84,7 @@ it('should open the popup when the button is clicked', () => {
togglePopup={toggle}
/>
);
- click(element.find('button'));
+ click(element.find('Button'));
expect(toggle.mock.calls).toMatchSnapshot();
element.setProps({ isOpen: true });
expect(element).toMatchSnapshot();
diff --git a/server/sonar-web/src/main/js/components/issue/components/__tests__/IssueType-test.js b/server/sonar-web/src/main/js/components/issue/components/__tests__/IssueType-test.js
index de6dcde42bf..51132f338ca 100644
--- a/server/sonar-web/src/main/js/components/issue/components/__tests__/IssueType-test.js
+++ b/server/sonar-web/src/main/js/components/issue/components/__tests__/IssueType-test.js
@@ -63,7 +63,7 @@ it('should open the popup when the button is clicked', () => {
togglePopup={toggle}
/>
);
- click(element.find('button'));
+ click(element.find('Button'));
expect(toggle.mock.calls).toMatchSnapshot();
element.setProps({ isOpen: true });
expect(element).toMatchSnapshot();
diff --git a/server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueAssign-test.js.snap b/server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueAssign-test.js.snap
index d4ff90579c6..d768c0c852d 100644
--- a/server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueAssign-test.js.snap
+++ b/server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueAssign-test.js.snap
@@ -4,112 +4,111 @@ exports[`should open the popup when the button is clicked 1`] = `
Array [
Array [
"assign",
- Object {
- "currentTarget": Object {
- "blur": [Function],
- },
- "preventDefault": [Function],
- "stopPropagation": [Function],
- "target": Object {
- "blur": [Function],
- },
- },
+ undefined,
],
]
`;
exports[`should open the popup when the button is clicked 2`] = `
-<BubblePopupHelper
- isOpen={true}
- popup={
- <Connect(SetAssigneePopup)
- issue={
- Object {
- "assignee": "john",
- "assigneeAvatar": "gravatarhash",
- "assigneeName": "John Doe",
- }
- }
- onFail={[MockFunction]}
- onSelect={[MockFunction]}
- />
- }
- position="bottomleft"
- togglePopup={[Function]}
+<div
+ className="dropdown"
>
- <button
- className="button-link issue-action issue-action-with-options js-issue-assign"
- onClick={[Function]}
+ <Toggler
+ closeOnEscape={true}
+ onRequestClose={[Function]}
+ open={true}
+ overlay={
+ <Connect(SetAssigneePopup)
+ issue={
+ Object {
+ "assignee": "john",
+ "assigneeAvatar": "gravatarhash",
+ "assigneeName": "John Doe",
+ }
+ }
+ onFail={[MockFunction]}
+ onSelect={[MockFunction]}
+ />
+ }
>
- <span>
- <span
- className="text-top"
- >
- <Connect(Avatar)
- className="little-spacer-right"
- hash="gravatarhash"
- name="John Doe"
- size={16}
- />
+ <Button
+ className="button-link issue-action issue-action-with-options js-issue-assign"
+ onClick={[Function]}
+ >
+ <span>
+ <span
+ className="text-top"
+ >
+ <Connect(Avatar)
+ className="little-spacer-right"
+ hash="gravatarhash"
+ name="John Doe"
+ size={16}
+ />
+ </span>
+ <span
+ className="issue-meta-label"
+ >
+ John Doe
+ </span>
</span>
- <span
- className="issue-meta-label"
- >
- John Doe
- </span>
- </span>
- <i
- className="little-spacer-left icon-dropdown"
- />
- </button>
-</BubblePopupHelper>
+ <DropdownIcon
+ className="little-spacer-left"
+ />
+ </Button>
+ </Toggler>
+</div>
`;
exports[`should render with the action 1`] = `
-<BubblePopupHelper
- isOpen={false}
- popup={
- <Connect(SetAssigneePopup)
- issue={
- Object {
- "assignee": "john",
- "assigneeAvatar": "gravatarhash",
- "assigneeName": "John Doe",
- }
- }
- onFail={[MockFunction]}
- onSelect={[MockFunction]}
- />
- }
- position="bottomleft"
- togglePopup={[Function]}
+<div
+ className="dropdown"
>
- <button
- className="button-link issue-action issue-action-with-options js-issue-assign"
- onClick={[Function]}
+ <Toggler
+ closeOnEscape={true}
+ onRequestClose={[Function]}
+ open={false}
+ overlay={
+ <Connect(SetAssigneePopup)
+ issue={
+ Object {
+ "assignee": "john",
+ "assigneeAvatar": "gravatarhash",
+ "assigneeName": "John Doe",
+ }
+ }
+ onFail={[MockFunction]}
+ onSelect={[MockFunction]}
+ />
+ }
>
- <span>
- <span
- className="text-top"
- >
- <Connect(Avatar)
- className="little-spacer-right"
- hash="gravatarhash"
- name="John Doe"
- size={16}
- />
+ <Button
+ className="button-link issue-action issue-action-with-options js-issue-assign"
+ onClick={[Function]}
+ >
+ <span>
+ <span
+ className="text-top"
+ >
+ <Connect(Avatar)
+ className="little-spacer-right"
+ hash="gravatarhash"
+ name="John Doe"
+ size={16}
+ />
+ </span>
+ <span
+ className="issue-meta-label"
+ >
+ John Doe
+ </span>
</span>
- <span
- className="issue-meta-label"
- >
- John Doe
- </span>
- </span>
- <i
- className="little-spacer-left icon-dropdown"
- />
- </button>
-</BubblePopupHelper>
+ <DropdownIcon
+ className="little-spacer-left"
+ />
+ </Button>
+ </Toggler>
+</div>
`;
exports[`should render without the action when the correct rights are missing 1`] = `
diff --git a/server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueChangelog-test.js.snap b/server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueChangelog-test.js.snap
index 97f8c58d32a..0628de785bf 100644
--- a/server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueChangelog-test.js.snap
+++ b/server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueChangelog-test.js.snap
@@ -10,91 +10,97 @@ Array [
`;
exports[`should open the popup when the button is clicked 2`] = `
-<BubblePopupHelper
- isOpen={true}
- popup={
- <ChangelogPopup
- issue={
- Object {
- "author": "john.david.dalton@gmail.com",
- "creationDate": "2017-03-01T09:36:01+0100",
- "key": "issuekey",
- }
- }
- onFail={[MockFunction]}
- />
- }
- position="bottomright"
- togglePopup={[Function]}
+<div
+ className="dropdown"
>
- <Tooltip
- mouseEnterDelay={0.5}
+ <Toggler
+ onRequestClose={[Function]}
+ open={true}
overlay={
- <DateTimeFormatter
- date="2017-03-01T09:36:01+0100"
+ <ChangelogPopup
+ issue={
+ Object {
+ "author": "john.david.dalton@gmail.com",
+ "creationDate": "2017-03-01T09:36:01+0100",
+ "key": "issuekey",
+ }
+ }
+ onFail={[MockFunction]}
/>
}
>
- <button
- className="button-link issue-action issue-action-with-options js-issue-show-changelog"
- onClick={[Function]}
+ <Tooltip
+ mouseEnterDelay={0.5}
+ overlay={
+ <DateTimeFormatter
+ date="2017-03-01T09:36:01+0100"
+ />
+ }
>
- <span
- className="issue-meta-label"
+ <Button
+ className="button-link issue-action issue-action-with-options js-issue-show-changelog"
+ onClick={[Function]}
>
- <DateFromNow
- date="2017-03-01T09:36:01+0100"
+ <span
+ className="issue-meta-label"
+ >
+ <DateFromNow
+ date="2017-03-01T09:36:01+0100"
+ />
+ </span>
+ <i
+ className="icon-dropdown little-spacer-left"
/>
- </span>
- <i
- className="icon-dropdown little-spacer-left"
- />
- </button>
- </Tooltip>
-</BubblePopupHelper>
+ </Button>
+ </Tooltip>
+ </Toggler>
+</div>
`;
exports[`should render correctly 1`] = `
-<BubblePopupHelper
- isOpen={false}
- popup={
- <ChangelogPopup
- issue={
- Object {
- "author": "john.david.dalton@gmail.com",
- "creationDate": "2017-03-01T09:36:01+0100",
- "key": "issuekey",
- }
- }
- onFail={[MockFunction]}
- />
- }
- position="bottomright"
- togglePopup={[Function]}
+<div
+ className="dropdown"
>
- <Tooltip
- mouseEnterDelay={0.5}
+ <Toggler
+ onRequestClose={[Function]}
+ open={false}
overlay={
- <DateTimeFormatter
- date="2017-03-01T09:36:01+0100"
+ <ChangelogPopup
+ issue={
+ Object {
+ "author": "john.david.dalton@gmail.com",
+ "creationDate": "2017-03-01T09:36:01+0100",
+ "key": "issuekey",
+ }
+ }
+ onFail={[MockFunction]}
/>
}
>
- <button
- className="button-link issue-action issue-action-with-options js-issue-show-changelog"
- onClick={[Function]}
+ <Tooltip
+ mouseEnterDelay={0.5}
+ overlay={
+ <DateTimeFormatter
+ date="2017-03-01T09:36:01+0100"
+ />
+ }
>
- <span
- className="issue-meta-label"
+ <Button
+ className="button-link issue-action issue-action-with-options js-issue-show-changelog"
+ onClick={[Function]}
>
- <DateFromNow
- date="2017-03-01T09:36:01+0100"
+ <span
+ className="issue-meta-label"
+ >
+ <DateFromNow
+ date="2017-03-01T09:36:01+0100"
+ />
+ </span>
+ <i
+ className="icon-dropdown little-spacer-left"
/>
- </span>
- <i
- className="icon-dropdown little-spacer-left"
- />
- </button>
- </Tooltip>
-</BubblePopupHelper>
+ </Button>
+ </Tooltip>
+ </Toggler>
+</div>
`;
diff --git a/server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueCommentAction-test.js.snap b/server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueCommentAction-test.js.snap
index 7305e5d8472..3c62307690e 100644
--- a/server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueCommentAction-test.js.snap
+++ b/server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueCommentAction-test.js.snap
@@ -2,13 +2,13 @@
exports[`should open the popup when the button is clicked 1`] = `
<li
- className="issue-meta"
+ className="issue-meta dropdown"
>
- <BubblePopupHelper
- isOpen={true}
- popup={
+ <Toggler
+ onRequestClose={[Function]}
+ open={true}
+ overlay={
<CommentPopup
- customClass="issue-comment-bubble-popup"
onComment={[Function]}
placeholder={undefined}
toggleComment={
@@ -20,16 +20,8 @@ exports[`should open the popup when the button is clicked 1`] = `
}
/>
}
- position="bottomleft"
- togglePopup={
- [MockFunction] {
- "calls": Array [
- Array [],
- ],
- }
- }
>
- <button
+ <Button
className="button-link issue-action js-issue-comment"
onClick={[Function]}
>
@@ -38,29 +30,27 @@ exports[`should open the popup when the button is clicked 1`] = `
>
issue.comment.formlink
</span>
- </button>
- </BubblePopupHelper>
+ </Button>
+ </Toggler>
</li>
`;
exports[`should render correctly 1`] = `
<li
- className="issue-meta"
+ className="issue-meta dropdown"
>
- <BubblePopupHelper
- isOpen={false}
- popup={
+ <Toggler
+ onRequestClose={[Function]}
+ open={false}
+ overlay={
<CommentPopup
- customClass="issue-comment-bubble-popup"
onComment={[Function]}
placeholder={undefined}
toggleComment={[MockFunction]}
/>
}
- position="bottomleft"
- togglePopup={[MockFunction]}
>
- <button
+ <Button
className="button-link issue-action js-issue-comment"
onClick={[Function]}
>
@@ -69,7 +59,7 @@ exports[`should render correctly 1`] = `
>
issue.comment.formlink
</span>
- </button>
- </BubblePopupHelper>
+ </Button>
+ </Toggler>
</li>
`;
diff --git a/server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueCommentLine-test.js.snap b/server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueCommentLine-test.js.snap
index 71f4ef39f22..4db5ed5aa9c 100644
--- a/server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueCommentLine-test.js.snap
+++ b/server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueCommentLine-test.js.snap
@@ -35,9 +35,6 @@ exports[`should open the right popups when the buttons are clicked 3`] = `
"__html": "<b>test</b>",
}
}
- onClick={[Function]}
- role="Listitem"
- tabIndex={0}
/>
<div
className="issue-comment-age"
@@ -49,63 +46,56 @@ exports[`should open the right popups when the buttons are clicked 3`] = `
<div
className="issue-comment-actions"
>
- <BubblePopupHelper
- className="bubble-popup-helper-inline"
- isOpen={false}
- offset={
- Object {
- "horizontal": -6,
- "vertical": 0,
- }
- }
- popup={
- <CommentPopup
- comment={
- Object {
- "authorAvatar": "gravatarhash",
- "authorName": "John Doe",
- "createdAt": "2017-03-01T09:36:01+0100",
- "htmlText": "<b>test</b>",
- "key": "comment-key",
- "updatable": true,
+ <div
+ className="dropdown"
+ >
+ <Toggler
+ className="display-inline-block"
+ onRequestClose={[Function]}
+ open={false}
+ overlay={
+ <CommentPopup
+ comment={
+ Object {
+ "authorAvatar": "gravatarhash",
+ "authorName": "John Doe",
+ "createdAt": "2017-03-01T09:36:01+0100",
+ "htmlText": "<b>test</b>",
+ "key": "comment-key",
+ "updatable": true,
+ }
}
- }
- customClass="issue-edit-comment-bubble-popup"
- onComment={[Function]}
- placeholder=""
- toggleComment={[Function]}
+ onComment={[Function]}
+ placeholder=""
+ toggleComment={[Function]}
+ />
+ }
+ >
+ <EditButton
+ className="js-issue-comment-edit button-small"
+ onClick={[Function]}
/>
- }
- position="bottomright"
- togglePopup={[Function]}
+ </Toggler>
+ </div>
+ <div
+ className="dropdown"
>
- <EditButton
- className="js-issue-comment-edit button-small"
- onClick={[Function]}
- />
- </BubblePopupHelper>
- <BubblePopupHelper
- className="bubble-popup-helper-inline"
- isOpen={true}
- offset={
- Object {
- "horizontal": -10,
- "vertical": 0,
+ <Toggler
+ className="display-inline-block"
+ onRequestClose={[Function]}
+ open={true}
+ overlay={
+ <CommentDeletePopup
+ onDelete={[Function]}
+ />
}
- }
- popup={
- <CommentDeletePopup
- onDelete={[Function]}
+ >
+ <DeleteButton
+ className="js-issue-comment-delete button-small"
+ onClick={[Function]}
/>
- }
- position="bottomright"
- togglePopup={[Function]}
- >
- <DeleteButton
- className="js-issue-comment-delete button-small"
- onClick={[Function]}
- />
- </BubblePopupHelper>
+ </Toggler>
+ </div>
</div>
</div>
`;
@@ -133,9 +123,6 @@ exports[`should render correctly a comment that is not updatable 1`] = `
"__html": "<b>test</b>",
}
}
- onClick={[Function]}
- role="Listitem"
- tabIndex={0}
/>
<div
className="issue-comment-age"
@@ -173,9 +160,6 @@ exports[`should render correctly a comment that is updatable 1`] = `
"__html": "<b>test</b>",
}
}
- onClick={[Function]}
- role="Listitem"
- tabIndex={0}
/>
<div
className="issue-comment-age"
@@ -187,63 +171,56 @@ exports[`should render correctly a comment that is updatable 1`] = `
<div
className="issue-comment-actions"
>
- <BubblePopupHelper
- className="bubble-popup-helper-inline"
- isOpen={false}
- offset={
- Object {
- "horizontal": -6,
- "vertical": 0,
- }
- }
- popup={
- <CommentPopup
- comment={
- Object {
- "authorAvatar": "gravatarhash",
- "authorName": "John Doe",
- "createdAt": "2017-03-01T09:36:01+0100",
- "htmlText": "<b>test</b>",
- "key": "comment-key",
- "updatable": true,
+ <div
+ className="dropdown"
+ >
+ <Toggler
+ className="display-inline-block"
+ onRequestClose={[Function]}
+ open={false}
+ overlay={
+ <CommentPopup
+ comment={
+ Object {
+ "authorAvatar": "gravatarhash",
+ "authorName": "John Doe",
+ "createdAt": "2017-03-01T09:36:01+0100",
+ "htmlText": "<b>test</b>",
+ "key": "comment-key",
+ "updatable": true,
+ }
}
- }
- customClass="issue-edit-comment-bubble-popup"
- onComment={[Function]}
- placeholder=""
- toggleComment={[Function]}
+ onComment={[Function]}
+ placeholder=""
+ toggleComment={[Function]}
+ />
+ }
+ >
+ <EditButton
+ className="js-issue-comment-edit button-small"
+ onClick={[Function]}
/>
- }
- position="bottomright"
- togglePopup={[Function]}
+ </Toggler>
+ </div>
+ <div
+ className="dropdown"
>
- <EditButton
- className="js-issue-comment-edit button-small"
- onClick={[Function]}
- />
- </BubblePopupHelper>
- <BubblePopupHelper
- className="bubble-popup-helper-inline"
- isOpen={false}
- offset={
- Object {
- "horizontal": -10,
- "vertical": 0,
+ <Toggler
+ className="display-inline-block"
+ onRequestClose={[Function]}
+ open={false}
+ overlay={
+ <CommentDeletePopup
+ onDelete={[Function]}
+ />
}
- }
- popup={
- <CommentDeletePopup
- onDelete={[Function]}
+ >
+ <DeleteButton
+ className="js-issue-comment-delete button-small"
+ onClick={[Function]}
/>
- }
- position="bottomright"
- togglePopup={[Function]}
- >
- <DeleteButton
- className="js-issue-comment-delete button-small"
- onClick={[Function]}
- />
- </BubblePopupHelper>
+ </Toggler>
+ </div>
</div>
</div>
`;
diff --git a/server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueSeverity-test.js.snap b/server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueSeverity-test.js.snap
index 98eb8644b75..898a75fd3d6 100644
--- a/server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueSeverity-test.js.snap
+++ b/server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueSeverity-test.js.snap
@@ -4,80 +4,77 @@ exports[`should open the popup when the button is clicked 1`] = `
Array [
Array [
"set-severity",
- Object {
- "currentTarget": Object {
- "blur": [Function],
- },
- "preventDefault": [Function],
- "stopPropagation": [Function],
- "target": Object {
- "blur": [Function],
- },
- },
+ undefined,
],
]
`;
exports[`should open the popup when the button is clicked 2`] = `
-<BubblePopupHelper
- isOpen={true}
- popup={
- <SetSeverityPopup
- issue={
- Object {
- "severity": "BLOCKER",
- }
- }
- onSelect={[Function]}
- />
- }
- position="bottomleft"
- togglePopup={[Function]}
+<div
+ className="dropdown"
>
- <button
- className="button-link issue-action issue-action-with-options js-issue-set-severity"
- onClick={[Function]}
+ <Toggler
+ onRequestClose={[Function]}
+ open={true}
+ overlay={
+ <SetSeverityPopup
+ issue={
+ Object {
+ "severity": "BLOCKER",
+ }
+ }
+ onSelect={[Function]}
+ />
+ }
>
- <SeverityHelper
- className="issue-meta-label little-spacer-right"
- severity="BLOCKER"
- />
- <i
- className="little-spacer-left icon-dropdown"
- />
- </button>
-</BubblePopupHelper>
+ <Button
+ className="button-link issue-action issue-action-with-options js-issue-set-severity"
+ onClick={[Function]}
+ >
+ <SeverityHelper
+ className="issue-meta-label"
+ severity="BLOCKER"
+ />
+ <DropdownIcon
+ className="little-spacer-left"
+ />
+ </Button>
+ </Toggler>
+</div>
`;
exports[`should render with the action 1`] = `
-<BubblePopupHelper
- isOpen={false}
- popup={
- <SetSeverityPopup
- issue={
- Object {
- "severity": "BLOCKER",
- }
- }
- onSelect={[Function]}
- />
- }
- position="bottomleft"
- togglePopup={[Function]}
+<div
+ className="dropdown"
>
- <button
- className="button-link issue-action issue-action-with-options js-issue-set-severity"
- onClick={[Function]}
+ <Toggler
+ onRequestClose={[Function]}
+ open={false}
+ overlay={
+ <SetSeverityPopup
+ issue={
+ Object {
+ "severity": "BLOCKER",
+ }
+ }
+ onSelect={[Function]}
+ />
+ }
>
- <SeverityHelper
- className="issue-meta-label little-spacer-right"
- severity="BLOCKER"
- />
- <i
- className="little-spacer-left icon-dropdown"
- />
- </button>
-</BubblePopupHelper>
+ <Button
+ className="button-link issue-action issue-action-with-options js-issue-set-severity"
+ onClick={[Function]}
+ >
+ <SeverityHelper
+ className="issue-meta-label"
+ severity="BLOCKER"
+ />
+ <DropdownIcon
+ className="little-spacer-left"
+ />
+ </Button>
+ </Toggler>
+</div>
`;
exports[`should render without the action when the correct rights are missing 1`] = `
diff --git a/server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueTags-test.js.snap b/server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueTags-test.js.snap
index fa30aff7c20..ca33fb7f1ec 100644
--- a/server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueTags-test.js.snap
+++ b/server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueTags-test.js.snap
@@ -4,88 +4,85 @@ exports[`should open the popup when the button is clicked 1`] = `
Array [
Array [
"edit-tags",
- Object {
- "currentTarget": Object {
- "blur": [Function],
- },
- "preventDefault": [Function],
- "stopPropagation": [Function],
- "target": Object {
- "blur": [Function],
- },
- },
+ undefined,
],
]
`;
exports[`should open the popup when the button is clicked 2`] = `
-<BubblePopupHelper
- isOpen={true}
- popup={
- <SetIssueTagsPopup
- organization="foo"
- selectedTags={
- Array [
- "mytag",
- "test",
- ]
- }
- setTags={[Function]}
- />
- }
- position="bottomright"
- togglePopup={[Function]}
+<div
+ className="dropdown"
>
- <button
- className="js-issue-edit-tags button-link issue-action issue-action-with-options"
- onClick={[Function]}
+ <Toggler
+ onRequestClose={[Function]}
+ open={true}
+ overlay={
+ <SetIssueTagsPopup
+ organization="foo"
+ selectedTags={
+ Array [
+ "mytag",
+ "test",
+ ]
+ }
+ setTags={[Function]}
+ />
+ }
>
- <TagsList
- allowUpdate={true}
- tags={
- Array [
- "mytag",
- "test",
- ]
- }
- />
- </button>
-</BubblePopupHelper>
+ <Button
+ className="js-issue-edit-tags button-link issue-action issue-action-with-options"
+ onClick={[Function]}
+ >
+ <TagsList
+ allowUpdate={true}
+ tags={
+ Array [
+ "mytag",
+ "test",
+ ]
+ }
+ />
+ </Button>
+ </Toggler>
+</div>
`;
exports[`should render with the action 1`] = `
-<BubblePopupHelper
- isOpen={false}
- popup={
- <SetIssueTagsPopup
- organization="foo"
- selectedTags={
- Array [
- "mytag",
- "test",
- ]
- }
- setTags={[Function]}
- />
- }
- position="bottomright"
- togglePopup={[Function]}
+<div
+ className="dropdown"
>
- <button
- className="js-issue-edit-tags button-link issue-action issue-action-with-options"
- onClick={[Function]}
+ <Toggler
+ onRequestClose={[Function]}
+ open={false}
+ overlay={
+ <SetIssueTagsPopup
+ organization="foo"
+ selectedTags={
+ Array [
+ "mytag",
+ "test",
+ ]
+ }
+ setTags={[Function]}
+ />
+ }
>
- <TagsList
- allowUpdate={true}
- tags={
- Array [
- "mytag",
- "test",
- ]
- }
- />
- </button>
-</BubblePopupHelper>
+ <Button
+ className="js-issue-edit-tags button-link issue-action issue-action-with-options"
+ onClick={[Function]}
+ >
+ <TagsList
+ allowUpdate={true}
+ tags={
+ Array [
+ "mytag",
+ "test",
+ ]
+ }
+ />
+ </Button>
+ </Toggler>
+</div>
`;
exports[`should render without the action when the correct rights are missing 1`] = `
diff --git a/server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueTitleBar-test.js.snap b/server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueTitleBar-test.js.snap
index 30fc9e84c33..8f3694dd8d0 100644
--- a/server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueTitleBar-test.js.snap
+++ b/server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueTitleBar-test.js.snap
@@ -68,7 +68,6 @@ exports[`should render the titlebar correctly 1`] = `
>
<Link
className="js-issue-permalink link-no-underline"
- onClick={[Function]}
onlyActiveOnIndex={false}
style={Object {}}
target="_blank"
@@ -152,7 +151,6 @@ exports[`should render the titlebar with the filter 1`] = `
>
<Link
className="js-issue-permalink link-no-underline"
- onClick={[Function]}
onlyActiveOnIndex={false}
style={Object {}}
target="_blank"
diff --git a/server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueTransition-test.js.snap b/server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueTransition-test.js.snap
index cd14db53dd2..dcfe4ff35ea 100644
--- a/server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueTransition-test.js.snap
+++ b/server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueTransition-test.js.snap
@@ -4,118 +4,118 @@ exports[`should open the popup when the button is clicked 1`] = `
Array [
Array [
"transition",
- Object {
- "currentTarget": Object {
- "blur": [Function],
- },
- "preventDefault": [Function],
- "stopPropagation": [Function],
- "target": Object {
- "blur": [Function],
- },
- },
+ undefined,
],
]
`;
exports[`should open the popup when the button is clicked 2`] = `
-<BubblePopupHelper
- isOpen={true}
- popup={
- <SetTransitionPopup
- onSelect={[Function]}
- transitions={
- Array [
- "confirm",
- "resolve",
- "falsepositive",
- "wontfix",
- ]
- }
- />
- }
- position="bottomleft"
- togglePopup={[Function]}
+<div
+ className="dropdown"
>
- <button
- className="button-link issue-action issue-action-with-options js-issue-transition"
- onClick={[Function]}
+ <Toggler
+ onRequestClose={[Function]}
+ open={true}
+ overlay={
+ <SetTransitionPopup
+ onSelect={[Function]}
+ transitions={
+ Array [
+ "confirm",
+ "resolve",
+ "falsepositive",
+ "wontfix",
+ ]
+ }
+ />
+ }
>
- <StatusHelper
- className="issue-meta-label little-spacer-right"
- status="OPEN"
- />
- <i
- className="little-spacer-left icon-dropdown"
- />
- </button>
-</BubblePopupHelper>
+ <Button
+ className="button-link issue-action issue-action-with-options js-issue-transition"
+ onClick={[Function]}
+ >
+ <StatusHelper
+ className="issue-meta-label"
+ status="OPEN"
+ />
+ <DropdownIcon
+ className="little-spacer-left"
+ />
+ </Button>
+ </Toggler>
+</div>
`;
exports[`should render with a resolution 1`] = `
-<BubblePopupHelper
- isOpen={false}
- popup={
- <SetTransitionPopup
- onSelect={[Function]}
- transitions={
- Array [
- "reopen",
- ]
- }
- />
- }
- position="bottomleft"
- togglePopup={[Function]}
+<div
+ className="dropdown"
>
- <button
- className="button-link issue-action issue-action-with-options js-issue-transition"
- onClick={[Function]}
+ <Toggler
+ onRequestClose={[Function]}
+ open={false}
+ overlay={
+ <SetTransitionPopup
+ onSelect={[Function]}
+ transitions={
+ Array [
+ "reopen",
+ ]
+ }
+ />
+ }
>
- <StatusHelper
- className="issue-meta-label little-spacer-right"
- resolution="FIXED"
- status="RESOLVED"
- />
- <i
- className="little-spacer-left icon-dropdown"
- />
- </button>
-</BubblePopupHelper>
+ <Button
+ className="button-link issue-action issue-action-with-options js-issue-transition"
+ onClick={[Function]}
+ >
+ <StatusHelper
+ className="issue-meta-label"
+ resolution="FIXED"
+ status="RESOLVED"
+ />
+ <DropdownIcon
+ className="little-spacer-left"
+ />
+ </Button>
+ </Toggler>
+</div>
`;
exports[`should render with the action 1`] = `
-<BubblePopupHelper
- isOpen={false}
- popup={
- <SetTransitionPopup
- onSelect={[Function]}
- transitions={
- Array [
- "confirm",
- "resolve",
- "falsepositive",
- "wontfix",
- ]
- }
- />
- }
- position="bottomleft"
- togglePopup={[Function]}
+<div
+ className="dropdown"
>
- <button
- className="button-link issue-action issue-action-with-options js-issue-transition"
- onClick={[Function]}
+ <Toggler
+ onRequestClose={[Function]}
+ open={false}
+ overlay={
+ <SetTransitionPopup
+ onSelect={[Function]}
+ transitions={
+ Array [
+ "confirm",
+ "resolve",
+ "falsepositive",
+ "wontfix",
+ ]
+ }
+ />
+ }
>
- <StatusHelper
- className="issue-meta-label little-spacer-right"
- status="OPEN"
- />
- <i
- className="little-spacer-left icon-dropdown"
- />
- </button>
-</BubblePopupHelper>
+ <Button
+ className="button-link issue-action issue-action-with-options js-issue-transition"
+ onClick={[Function]}
+ >
+ <StatusHelper
+ className="issue-meta-label"
+ status="OPEN"
+ />
+ <DropdownIcon
+ className="little-spacer-left"
+ />
+ </Button>
+ </Toggler>
+</div>
`;
exports[`should render without the action when there is no transitions 1`] = `
diff --git a/server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueType-test.js.snap b/server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueType-test.js.snap
index 77988d1f003..1eb2844dbf6 100644
--- a/server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueType-test.js.snap
+++ b/server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueType-test.js.snap
@@ -4,82 +4,79 @@ exports[`should open the popup when the button is clicked 1`] = `
Array [
Array [
"set-type",
- Object {
- "currentTarget": Object {
- "blur": [Function],
- },
- "preventDefault": [Function],
- "stopPropagation": [Function],
- "target": Object {
- "blur": [Function],
- },
- },
+ undefined,
],
]
`;
exports[`should open the popup when the button is clicked 2`] = `
-<BubblePopupHelper
- isOpen={true}
- popup={
- <SetTypePopup
- issue={
- Object {
- "type": "bug",
- }
- }
- onSelect={[Function]}
- />
- }
- position="bottomleft"
- togglePopup={[Function]}
+<div
+ className="dropdown"
>
- <button
- className="button-link issue-action issue-action-with-options js-issue-set-type"
- onClick={[Function]}
+ <Toggler
+ onRequestClose={[Function]}
+ open={true}
+ overlay={
+ <SetTypePopup
+ issue={
+ Object {
+ "type": "bug",
+ }
+ }
+ onSelect={[Function]}
+ />
+ }
>
- <IssueTypeIcon
- className="little-spacer-right"
- query="bug"
- />
- issue.type.bug
- <i
- className="little-spacer-left icon-dropdown"
- />
- </button>
-</BubblePopupHelper>
+ <Button
+ className="button-link issue-action issue-action-with-options js-issue-set-type"
+ onClick={[Function]}
+ >
+ <IssueTypeIcon
+ className="little-spacer-right"
+ query="bug"
+ />
+ issue.type.bug
+ <DropdownIcon
+ className="little-spacer-left"
+ />
+ </Button>
+ </Toggler>
+</div>
`;
exports[`should render with the action 1`] = `
-<BubblePopupHelper
- isOpen={false}
- popup={
- <SetTypePopup
- issue={
- Object {
- "type": "bug",
- }
- }
- onSelect={[Function]}
- />
- }
- position="bottomleft"
- togglePopup={[Function]}
+<div
+ className="dropdown"
>
- <button
- className="button-link issue-action issue-action-with-options js-issue-set-type"
- onClick={[Function]}
+ <Toggler
+ onRequestClose={[Function]}
+ open={false}
+ overlay={
+ <SetTypePopup
+ issue={
+ Object {
+ "type": "bug",
+ }
+ }
+ onSelect={[Function]}
+ />
+ }
>
- <IssueTypeIcon
- className="little-spacer-right"
- query="bug"
- />
- issue.type.bug
- <i
- className="little-spacer-left icon-dropdown"
- />
- </button>
-</BubblePopupHelper>
+ <Button
+ className="button-link issue-action issue-action-with-options js-issue-set-type"
+ onClick={[Function]}
+ >
+ <IssueTypeIcon
+ className="little-spacer-right"
+ query="bug"
+ />
+ issue.type.bug
+ <DropdownIcon
+ className="little-spacer-left"
+ />
+ </Button>
+ </Toggler>
+</div>
`;
exports[`should render without the action when the correct rights are missing 1`] = `
diff --git a/server/sonar-web/src/main/js/components/issue/popups/ChangelogPopup.js b/server/sonar-web/src/main/js/components/issue/popups/ChangelogPopup.js
index b3f230810fe..fcfd515b587 100644
--- a/server/sonar-web/src/main/js/components/issue/popups/ChangelogPopup.js
+++ b/server/sonar-web/src/main/js/components/issue/popups/ChangelogPopup.js
@@ -22,9 +22,9 @@ import React from 'react';
import { getIssueChangelog } from '../../../api/issues';
import { translate } from '../../../helpers/l10n';
import Avatar from '../../../components/ui/Avatar';
-import BubblePopup from '../../../components/common/BubblePopup';
import DateTimeFormatter from '../../../components/intl/DateTimeFormatter';
import IssueChangelogDiff from '../components/IssueChangelogDiff';
+import { DropdownOverlay } from '../../controls/Dropdown';
/*:: import type { ChangelogDiff } from '../components/IssueChangelogDiff'; */
/*:: import type { Issue } from '../types'; */
@@ -80,8 +80,8 @@ export default class ChangelogPopup extends React.PureComponent {
const { issue } = this.props;
const { author } = issue;
return (
- <BubblePopup position={this.props.popupPosition} customClass="bubble-popup-bottom-right">
- <div className="issue-changelog">
+ <DropdownOverlay>
+ <div className="menu is-container issue-changelog">
<table className="spaced">
<tbody>
<tr>
@@ -110,14 +110,14 @@ export default class ChangelogPopup extends React.PureComponent {
{item.userName}
</p>
)}
- {item.diffs.map(diff => <IssueChangelogDiff key={diff.key} diff={diff} />)}
+ {item.diffs.map(diff => <IssueChangelogDiff diff={diff} key={diff.key} />)}
</td>
</tr>
))}
</tbody>
</table>
</div>
- </BubblePopup>
+ </DropdownOverlay>
);
}
}
diff --git a/server/sonar-web/src/main/js/components/issue/popups/CommentDeletePopup.js b/server/sonar-web/src/main/js/components/issue/popups/CommentDeletePopup.js
index 9776ab00253..c7fd5d89ae8 100644
--- a/server/sonar-web/src/main/js/components/issue/popups/CommentDeletePopup.js
+++ b/server/sonar-web/src/main/js/components/issue/popups/CommentDeletePopup.js
@@ -19,8 +19,9 @@
*/
// @flow
import React from 'react';
+import { Button } from '../../../components/ui/buttons';
import { translate } from '../../../helpers/l10n';
-import BubblePopup from '../../../components/common/BubblePopup';
+import { DropdownOverlay } from '../../controls/Dropdown';
/*::
type Props = {
@@ -31,13 +32,13 @@ type Props = {
export default function CommentDeletePopup(props /*: Props */) {
return (
- <BubblePopup position={props.popupPosition} customClass="bubble-popup-bottom-right">
- <div className="text-right">
+ <DropdownOverlay>
+ <div className="menu is-container">
<div className="spacer-bottom">{translate('issue.comment.delete_confirm_message')}</div>
- <button className="button-red" onClick={props.onDelete}>
+ <Button className="button-red" onClick={props.onDelete}>
{translate('delete')}
- </button>
+ </Button>
</div>
- </BubblePopup>
+ </DropdownOverlay>
);
}
diff --git a/server/sonar-web/src/main/js/components/issue/popups/CommentPopup.js b/server/sonar-web/src/main/js/components/issue/popups/CommentPopup.js
index 2a17f71383b..bee719a083e 100644
--- a/server/sonar-web/src/main/js/components/issue/popups/CommentPopup.js
+++ b/server/sonar-web/src/main/js/components/issue/popups/CommentPopup.js
@@ -19,16 +19,15 @@
*/
// @flow
import React from 'react';
-import classNames from 'classnames';
-import BubblePopup from '../../../components/common/BubblePopup';
import MarkdownTips from '../../../components/common/MarkdownTips';
+import { Button, ResetButtonLink } from '../../../components/ui/buttons';
import { translate } from '../../../helpers/l10n';
+import { DropdownOverlay } from '../../controls/Dropdown';
/*:: import type { IssueComment } from '../types'; */
/*::
type Props = {
comment?: IssueComment,
- customClass?: string,
onComment: string => void,
toggleComment: boolean => void,
placeholder: string,
@@ -63,8 +62,7 @@ export default class CommentPopup extends React.PureComponent {
}
};
- handleCancelClick = (evt /*: MouseEvent */) => {
- evt.preventDefault();
+ handleCancelClick = () => {
this.props.toggleComment(false);
};
@@ -81,37 +79,37 @@ export default class CommentPopup extends React.PureComponent {
render() {
const { comment } = this.props;
return (
- <BubblePopup
- position={this.props.popupPosition}
- customClass={classNames(this.props.customClass, 'bubble-popup-bottom-right')}>
- <div className="issue-comment-form-text">
- <textarea
- autoFocus={true}
- placeholder={this.props.placeholder}
- onChange={this.handleCommentChange}
- onKeyDown={this.handleKeyboard}
- value={this.state.textComment}
- rows="2"
- />
- </div>
- <div className="issue-comment-form-footer">
- <div className="issue-comment-form-actions">
- <button
- className="js-issue-comment-submit little-spacer-right"
- disabled={this.state.textComment.trim().length < 1}
- onClick={this.handleCommentClick}>
- {comment && translate('save')}
- {!comment && translate('issue.comment.submit')}
- </button>
- <a href="#" className="js-issue-comment-cancel" onClick={this.handleCancelClick}>
- {translate('cancel')}
- </a>
+ <DropdownOverlay>
+ <div className="issue-comment-bubble-popup">
+ <div className="issue-comment-form-text">
+ <textarea
+ autoFocus={true}
+ onChange={this.handleCommentChange}
+ onKeyDown={this.handleKeyboard}
+ placeholder={this.props.placeholder}
+ rows="2"
+ value={this.state.textComment}
+ />
</div>
- <div className="issue-comment-form-tips">
- <MarkdownTips />
+ <div className="issue-comment-form-footer">
+ <div className="issue-comment-form-actions">
+ <Button
+ className="js-issue-comment-submit little-spacer-right"
+ disabled={this.state.textComment.trim().length < 1}
+ onClick={this.handleCommentClick}>
+ {comment && translate('save')}
+ {!comment && translate('issue.comment.submit')}
+ </Button>
+ <ResetButtonLink className="js-issue-comment-cancel" onClick={this.handleCancelClick}>
+ {translate('cancel')}
+ </ResetButtonLink>
+ </div>
+ <div className="issue-comment-form-tips">
+ <MarkdownTips />
+ </div>
</div>
</div>
- </BubblePopup>
+ </DropdownOverlay>
);
}
}
diff --git a/server/sonar-web/src/main/js/components/issue/popups/SetAssigneePopup.js b/server/sonar-web/src/main/js/components/issue/popups/SetAssigneePopup.js
index 270cbe04158..b5658c997d3 100644
--- a/server/sonar-web/src/main/js/components/issue/popups/SetAssigneePopup.js
+++ b/server/sonar-web/src/main/js/components/issue/popups/SetAssigneePopup.js
@@ -23,7 +23,6 @@ import { map } from 'lodash';
import { connect } from 'react-redux';
import * as PropTypes from 'prop-types';
import Avatar from '../../../components/ui/Avatar';
-import BubblePopup from '../../../components/common/BubblePopup';
import SelectList from '../../../components/common/SelectList';
import SelectListItem from '../../../components/common/SelectListItem';
import SearchBox from '../../../components/controls/SearchBox';
@@ -31,6 +30,7 @@ import { searchMembers } from '../../../api/organizations';
import { searchUsers } from '../../../api/users';
import { translate } from '../../../helpers/l10n';
import { getCurrentUser } from '../../../store/rootReducer';
+import { DropdownOverlay } from '../../controls/Dropdown';
/*:: import type { Issue } from '../types'; */
/*::
@@ -123,9 +123,7 @@ class SetAssigneePopup extends React.PureComponent {
render() {
return (
- <BubblePopup
- customClass="bubble-popup-menu bubble-popup-bottom"
- position={this.props.popupPosition}>
+ <DropdownOverlay noPadding={true}>
<div className="multi-select">
<div className="menu-search">
<SearchBox
@@ -142,7 +140,7 @@ class SetAssigneePopup extends React.PureComponent {
items={map(this.state.users, 'login')}
onSelect={this.props.onSelect}>
{this.state.users.map(user => (
- <SelectListItem key={user.login} item={user.login}>
+ <SelectListItem item={user.login} key={user.login}>
{!!user.login && (
<Avatar className="spacer-right" hash={user.avatar} name={user.name} size={16} />
)}
@@ -155,7 +153,7 @@ class SetAssigneePopup extends React.PureComponent {
))}
</SelectList>
</div>
- </BubblePopup>
+ </DropdownOverlay>
);
}
}
diff --git a/server/sonar-web/src/main/js/components/issue/popups/SetIssueTagsPopup.tsx b/server/sonar-web/src/main/js/components/issue/popups/SetIssueTagsPopup.tsx
index 90b8af5f628..c41c216e8b6 100644
--- a/server/sonar-web/src/main/js/components/issue/popups/SetIssueTagsPopup.tsx
+++ b/server/sonar-web/src/main/js/components/issue/popups/SetIssueTagsPopup.tsx
@@ -19,12 +19,12 @@
*/
import * as React from 'react';
import { difference, without } from 'lodash';
-import { BubblePopupPosition } from '../../../components/common/BubblePopup';
import TagsSelector from '../../../components/tags/TagsSelector';
import { searchIssueTags } from '../../../api/issues';
+import { DropdownOverlay } from '../../controls/Dropdown';
+import { PopupPlacement } from '../../ui/popups';
interface Props {
- popupPosition: BubblePopupPosition;
organization: string;
selectedTags: string[];
setTags: (tags: string[]) => void;
@@ -74,15 +74,16 @@ export default class SetIssueTagsPopup extends React.PureComponent<Props, State>
render() {
const availableTags = difference(this.state.searchResult, this.props.selectedTags);
return (
- <TagsSelector
- listSize={LIST_SIZE}
- onSearch={this.onSearch}
- onSelect={this.onSelect}
- onUnselect={this.onUnselect}
- position={this.props.popupPosition}
- selectedTags={this.props.selectedTags}
- tags={availableTags}
- />
+ <DropdownOverlay placement={PopupPlacement.BottomRight}>
+ <TagsSelector
+ listSize={LIST_SIZE}
+ onSearch={this.onSearch}
+ onSelect={this.onSelect}
+ onUnselect={this.onUnselect}
+ selectedTags={this.props.selectedTags}
+ tags={availableTags}
+ />
+ </DropdownOverlay>
);
}
}
diff --git a/server/sonar-web/src/main/js/components/issue/popups/SetSeverityPopup.js b/server/sonar-web/src/main/js/components/issue/popups/SetSeverityPopup.js
index cc03b290475..2d3c2232f88 100644
--- a/server/sonar-web/src/main/js/components/issue/popups/SetSeverityPopup.js
+++ b/server/sonar-web/src/main/js/components/issue/popups/SetSeverityPopup.js
@@ -20,17 +20,16 @@
// @flow
import React from 'react';
import { translate } from '../../../helpers/l10n';
-import BubblePopup from '../../../components/common/BubblePopup';
import SelectList from '../../../components/common/SelectList';
import SelectListItem from '../../../components/common/SelectListItem';
import SeverityIcon from '../../../components/shared/SeverityIcon';
+import { DropdownOverlay } from '../../controls/Dropdown';
/*:: import type { Issue } from '../types'; */
/*::
type Props = {
issue: Issue,
onSelect: string => void,
- popupPosition?: {}
};
*/
@@ -41,21 +40,19 @@ export default class SetSeverityPopup extends React.PureComponent {
render() {
return (
- <BubblePopup
- position={this.props.popupPosition}
- customClass="bubble-popup-menu bubble-popup-bottom">
+ <DropdownOverlay>
<SelectList
- items={SEVERITY}
currentItem={this.props.issue.severity}
+ items={SEVERITY}
onSelect={this.props.onSelect}>
{SEVERITY.map(severity => (
- <SelectListItem key={severity} item={severity}>
+ <SelectListItem item={severity} key={severity}>
<SeverityIcon className="little-spacer-right" severity={severity} />
{translate('severity', severity)}
</SelectListItem>
))}
</SelectList>
- </BubblePopup>
+ </DropdownOverlay>
);
}
}
diff --git a/server/sonar-web/src/main/js/components/issue/popups/SetTransitionPopup.js b/server/sonar-web/src/main/js/components/issue/popups/SetTransitionPopup.js
index 44bf942253d..37d342f7eb2 100644
--- a/server/sonar-web/src/main/js/components/issue/popups/SetTransitionPopup.js
+++ b/server/sonar-web/src/main/js/components/issue/popups/SetTransitionPopup.js
@@ -19,16 +19,15 @@
*/
// @flow
import React from 'react';
-import BubblePopup from '../../../components/common/BubblePopup';
import SelectList from '../../../components/common/SelectList';
import SelectListItem from '../../../components/common/SelectListItem';
import { translate } from '../../../helpers/l10n';
+import { DropdownOverlay } from '../../controls/Dropdown';
/*::
type Props = {
transitions: Array<string>,
onSelect: string => void,
- popupPosition?: {}
};
*/
@@ -38,22 +37,20 @@ export default class SetTransitionPopup extends React.PureComponent {
render() {
const { transitions } = this.props;
return (
- <BubblePopup
- position={this.props.popupPosition}
- customClass="bubble-popup-menu bubble-popup-bottom">
- <SelectList items={transitions} currentItem={transitions[0]} onSelect={this.props.onSelect}>
+ <DropdownOverlay>
+ <SelectList currentItem={transitions[0]} items={transitions} onSelect={this.props.onSelect}>
{transitions.map(transition => {
return (
<SelectListItem
- key={transition}
item={transition}
+ key={transition}
title={translate('issue.transition', transition, 'description')}>
{translate('issue.transition', transition)}
</SelectListItem>
);
})}
</SelectList>
- </BubblePopup>
+ </DropdownOverlay>
);
}
}
diff --git a/server/sonar-web/src/main/js/components/issue/popups/SetTypePopup.js b/server/sonar-web/src/main/js/components/issue/popups/SetTypePopup.js
index f623afccd08..f69e07cf141 100644
--- a/server/sonar-web/src/main/js/components/issue/popups/SetTypePopup.js
+++ b/server/sonar-web/src/main/js/components/issue/popups/SetTypePopup.js
@@ -20,17 +20,16 @@
// @flow
import React from 'react';
import { translate } from '../../../helpers/l10n';
-import BubblePopup from '../../../components/common/BubblePopup';
import IssueTypeIcon from '../../../components/ui/IssueTypeIcon';
import SelectList from '../../../components/common/SelectList';
import SelectListItem from '../../../components/common/SelectListItem';
+import { DropdownOverlay } from '../../controls/Dropdown';
/*:: import type { Issue } from '../types'; */
/*::
type Props = {
issue: Issue,
onSelect: string => void,
- popupPosition?: {}
};
*/
@@ -41,21 +40,19 @@ export default class SetTypePopup extends React.PureComponent {
render() {
return (
- <BubblePopup
- position={this.props.popupPosition}
- customClass="bubble-popup-menu bubble-popup-bottom">
+ <DropdownOverlay>
<SelectList
- items={TYPES}
currentItem={this.props.issue.type}
+ items={TYPES}
onSelect={this.props.onSelect}>
{TYPES.map(type => (
- <SelectListItem key={type} item={type}>
+ <SelectListItem item={type} key={type}>
<IssueTypeIcon className="little-spacer-right" query={type} />
{translate('issue.type', type)}
</SelectListItem>
))}
</SelectList>
- </BubblePopup>
+ </DropdownOverlay>
);
}
}
diff --git a/server/sonar-web/src/main/js/components/issue/popups/SimilarIssuesPopup.js b/server/sonar-web/src/main/js/components/issue/popups/SimilarIssuesPopup.js
index fb9b24780e3..7a28c6594ed 100644
--- a/server/sonar-web/src/main/js/components/issue/popups/SimilarIssuesPopup.js
+++ b/server/sonar-web/src/main/js/components/issue/popups/SimilarIssuesPopup.js
@@ -19,9 +19,9 @@
*/
// @flow
import React from 'react';
-import BubblePopup from '../../../components/common/BubblePopup';
import SelectList from '../../../components/common/SelectList';
import SelectListItem from '../../../components/common/SelectListItem';
+import { DropdownOverlay } from '../../../components/controls/Dropdown';
import SeverityHelper from '../../../components/shared/SeverityHelper';
import StatusHelper from '../../../components/shared/StatusHelper';
import QualifierIcon from '../../../components/shared/QualifierIcon';
@@ -35,7 +35,6 @@ import { fileFromPath, limitComponentName } from '../../../helpers/path';
type Props = {|
issue: Issue,
onFilter: (property: string, issue: Issue) => void,
- popupPosition?: {}
|};
*/
@@ -64,9 +63,7 @@ export default class SimilarIssuesPopup extends React.PureComponent {
].filter(item => item);
return (
- <BubblePopup
- position={this.props.popupPosition}
- customClass="bubble-popup-menu bubble-popup-bottom-right">
+ <DropdownOverlay noPadding={true}>
<header className="menu-search">
<h6>{translate('issue.filter_similar_issues')}</h6>
</header>
@@ -118,7 +115,7 @@ export default class SimilarIssuesPopup extends React.PureComponent {
{issue.tags != null &&
issue.tags.map(tag => (
- <SelectListItem key={`tag###${tag}`} item={`tag###${tag}`}>
+ <SelectListItem item={`tag###${tag}`} key={`tag###${tag}`}>
<i className="icon-tags icon-half-transparent little-spacer-right" />
{tag}
</SelectListItem>
@@ -143,7 +140,7 @@ export default class SimilarIssuesPopup extends React.PureComponent {
{fileFromPath(issue.componentLongName)}
</SelectListItem>
</SelectList>
- </BubblePopup>
+ </DropdownOverlay>
);
}
}
diff --git a/server/sonar-web/src/main/js/components/issue/popups/__tests__/CommentDeletePopup-test.js b/server/sonar-web/src/main/js/components/issue/popups/__tests__/CommentDeletePopup-test.js
index 2256e3fb35a..be0c222335d 100644
--- a/server/sonar-web/src/main/js/components/issue/popups/__tests__/CommentDeletePopup-test.js
+++ b/server/sonar-web/src/main/js/components/issue/popups/__tests__/CommentDeletePopup-test.js
@@ -26,6 +26,6 @@ it('should render the comment delete popup correctly', () => {
const onDelete = jest.fn();
const element = shallow(<CommentDeletePopup onDelete={onDelete} />);
expect(element).toMatchSnapshot();
- click(element.find('button'));
+ click(element.find('Button'));
expect(onDelete.mock.calls.length).toBe(1);
});
diff --git a/server/sonar-web/src/main/js/components/issue/popups/__tests__/CommentPopup-test.js b/server/sonar-web/src/main/js/components/issue/popups/__tests__/CommentPopup-test.js
index 7716fe669a3..6cfd0dcdf64 100644
--- a/server/sonar-web/src/main/js/components/issue/popups/__tests__/CommentPopup-test.js
+++ b/server/sonar-web/src/main/js/components/issue/popups/__tests__/CommentPopup-test.js
@@ -25,10 +25,10 @@ import { click } from '../../../../helpers/testUtils';
it('should render the comment popup correctly without existing comment', () => {
const element = shallow(
<CommentPopup
+ customClass="myclass"
onComment={jest.fn()}
- toggleComment={jest.fn()}
placeholder="placeholder test"
- customClass="myclass"
+ toggleComment={jest.fn()}
/>
);
expect(element).toMatchSnapshot();
@@ -37,12 +37,10 @@ it('should render the comment popup correctly without existing comment', () => {
it('should render the comment popup correctly when changing a comment', () => {
const element = shallow(
<CommentPopup
- comment={{
- markdown: '*test*'
- }}
+ comment={{ markdown: '*test*' }}
onComment={jest.fn()}
- toggleComment={jest.fn()}
placeholder=""
+ toggleComment={jest.fn()}
/>
);
expect(element).toMatchSnapshot();
@@ -52,15 +50,15 @@ it('should render not allow to send comment with only spaces', () => {
const onComment = jest.fn();
const element = shallow(
<CommentPopup
+ customClass="myclass"
onComment={onComment}
- toggleComment={jest.fn()}
placeholder="placeholder test"
- customClass="myclass"
+ toggleComment={jest.fn()}
/>
);
- click(element.find('button.js-issue-comment-submit'));
+ click(element.find('.js-issue-comment-submit'));
expect(onComment.mock.calls.length).toBe(0);
element.setState({ textComment: 'mycomment' });
- click(element.find('button.js-issue-comment-submit'));
+ click(element.find('.js-issue-comment-submit'));
expect(onComment.mock.calls.length).toBe(1);
});
diff --git a/server/sonar-web/src/main/js/components/issue/popups/__tests__/SetIssueTagsPopup-test.tsx b/server/sonar-web/src/main/js/components/issue/popups/__tests__/SetIssueTagsPopup-test.tsx
index f66e329ec87..00b85fd1817 100644
--- a/server/sonar-web/src/main/js/components/issue/popups/__tests__/SetIssueTagsPopup-test.tsx
+++ b/server/sonar-web/src/main/js/components/issue/popups/__tests__/SetIssueTagsPopup-test.tsx
@@ -23,12 +23,7 @@ import SetIssueTagsPopup from '../SetIssueTagsPopup';
it('should render tags popup correctly', () => {
const element = shallow(
- <SetIssueTagsPopup
- organization="foo"
- popupPosition={{}}
- selectedTags={['mytag']}
- setTags={jest.fn()}
- />
+ <SetIssueTagsPopup organization="foo" selectedTags={['mytag']} setTags={jest.fn()} />
);
element.setState({ searchResult: ['mytag', 'test', 'second'] });
expect(element).toMatchSnapshot();
diff --git a/server/sonar-web/src/main/js/components/issue/popups/__tests__/__snapshots__/ChangelogPopup-test.js.snap b/server/sonar-web/src/main/js/components/issue/popups/__tests__/__snapshots__/ChangelogPopup-test.js.snap
index 65cade73cf8..f54cfd88b77 100644
--- a/server/sonar-web/src/main/js/components/issue/popups/__tests__/__snapshots__/ChangelogPopup-test.js.snap
+++ b/server/sonar-web/src/main/js/components/issue/popups/__tests__/__snapshots__/ChangelogPopup-test.js.snap
@@ -1,11 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`should render the changelog popup correctly 1`] = `
-<BubblePopup
- customClass="bubble-popup-bottom-right"
->
+<DropdownOverlay>
<div
- className="issue-changelog"
+ className="menu is-container issue-changelog"
>
<table
className="spaced"
@@ -62,5 +60,5 @@ exports[`should render the changelog popup correctly 1`] = `
</tbody>
</table>
</div>
-</BubblePopup>
+</DropdownOverlay>
`;
diff --git a/server/sonar-web/src/main/js/components/issue/popups/__tests__/__snapshots__/CommentDeletePopup-test.js.snap b/server/sonar-web/src/main/js/components/issue/popups/__tests__/__snapshots__/CommentDeletePopup-test.js.snap
index 634b35907be..43c00928943 100644
--- a/server/sonar-web/src/main/js/components/issue/popups/__tests__/__snapshots__/CommentDeletePopup-test.js.snap
+++ b/server/sonar-web/src/main/js/components/issue/popups/__tests__/__snapshots__/CommentDeletePopup-test.js.snap
@@ -1,23 +1,21 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`should render the comment delete popup correctly 1`] = `
-<BubblePopup
- customClass="bubble-popup-bottom-right"
->
+<DropdownOverlay>
<div
- className="text-right"
+ className="menu is-container"
>
<div
className="spacer-bottom"
>
issue.comment.delete_confirm_message
</div>
- <button
+ <Button
className="button-red"
onClick={[MockFunction]}
>
delete
- </button>
+ </Button>
</div>
-</BubblePopup>
+</DropdownOverlay>
`;
diff --git a/server/sonar-web/src/main/js/components/issue/popups/__tests__/__snapshots__/CommentPopup-test.js.snap b/server/sonar-web/src/main/js/components/issue/popups/__tests__/__snapshots__/CommentPopup-test.js.snap
index d33898199b7..8ed5e9eb55a 100644
--- a/server/sonar-web/src/main/js/components/issue/popups/__tests__/__snapshots__/CommentPopup-test.js.snap
+++ b/server/sonar-web/src/main/js/components/issue/popups/__tests__/__snapshots__/CommentPopup-test.js.snap
@@ -1,93 +1,95 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`should render the comment popup correctly when changing a comment 1`] = `
-<BubblePopup
- customClass="bubble-popup-bottom-right"
->
+<DropdownOverlay>
<div
- className="issue-comment-form-text"
- >
- <textarea
- autoFocus={true}
- onChange={[Function]}
- onKeyDown={[Function]}
- placeholder=""
- rows="2"
- value="*test*"
- />
- </div>
- <div
- className="issue-comment-form-footer"
+ className="issue-comment-bubble-popup"
>
<div
- className="issue-comment-form-actions"
+ className="issue-comment-form-text"
>
- <button
- className="js-issue-comment-submit little-spacer-right"
- disabled={false}
- onClick={[Function]}
- >
- save
- </button>
- <a
- className="js-issue-comment-cancel"
- href="#"
- onClick={[Function]}
- >
- cancel
- </a>
+ <textarea
+ autoFocus={true}
+ onChange={[Function]}
+ onKeyDown={[Function]}
+ placeholder=""
+ rows="2"
+ value="*test*"
+ />
</div>
<div
- className="issue-comment-form-tips"
+ className="issue-comment-form-footer"
>
- <MarkdownTips />
+ <div
+ className="issue-comment-form-actions"
+ >
+ <Button
+ className="js-issue-comment-submit little-spacer-right"
+ disabled={false}
+ onClick={[Function]}
+ >
+ save
+ </Button>
+ <ResetButtonLink
+ className="js-issue-comment-cancel"
+ onClick={[Function]}
+ >
+ cancel
+ </ResetButtonLink>
+ </div>
+ <div
+ className="issue-comment-form-tips"
+ >
+ <MarkdownTips />
+ </div>
</div>
</div>
-</BubblePopup>
+</DropdownOverlay>
`;
exports[`should render the comment popup correctly without existing comment 1`] = `
-<BubblePopup
- customClass="myclass bubble-popup-bottom-right"
->
+<DropdownOverlay>
<div
- className="issue-comment-form-text"
- >
- <textarea
- autoFocus={true}
- onChange={[Function]}
- onKeyDown={[Function]}
- placeholder="placeholder test"
- rows="2"
- value=""
- />
- </div>
- <div
- className="issue-comment-form-footer"
+ className="issue-comment-bubble-popup"
>
<div
- className="issue-comment-form-actions"
+ className="issue-comment-form-text"
>
- <button
- className="js-issue-comment-submit little-spacer-right"
- disabled={true}
- onClick={[Function]}
- >
- issue.comment.submit
- </button>
- <a
- className="js-issue-comment-cancel"
- href="#"
- onClick={[Function]}
- >
- cancel
- </a>
+ <textarea
+ autoFocus={true}
+ onChange={[Function]}
+ onKeyDown={[Function]}
+ placeholder="placeholder test"
+ rows="2"
+ value=""
+ />
</div>
<div
- className="issue-comment-form-tips"
+ className="issue-comment-form-footer"
>
- <MarkdownTips />
+ <div
+ className="issue-comment-form-actions"
+ >
+ <Button
+ className="js-issue-comment-submit little-spacer-right"
+ disabled={true}
+ onClick={[Function]}
+ >
+ issue.comment.submit
+ </Button>
+ <ResetButtonLink
+ className="js-issue-comment-cancel"
+ onClick={[Function]}
+ >
+ cancel
+ </ResetButtonLink>
+ </div>
+ <div
+ className="issue-comment-form-tips"
+ >
+ <MarkdownTips />
+ </div>
</div>
</div>
-</BubblePopup>
+</DropdownOverlay>
`;
diff --git a/server/sonar-web/src/main/js/components/issue/popups/__tests__/__snapshots__/SetIssueTagsPopup-test.tsx.snap b/server/sonar-web/src/main/js/components/issue/popups/__tests__/__snapshots__/SetIssueTagsPopup-test.tsx.snap
index 57990df2131..a5eb2aafcac 100644
--- a/server/sonar-web/src/main/js/components/issue/popups/__tests__/__snapshots__/SetIssueTagsPopup-test.tsx.snap
+++ b/server/sonar-web/src/main/js/components/issue/popups/__tests__/__snapshots__/SetIssueTagsPopup-test.tsx.snap
@@ -1,22 +1,25 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`should render tags popup correctly 1`] = `
-<TagsSelector
- listSize={10}
- onSearch={[Function]}
- onSelect={[Function]}
- onUnselect={[Function]}
- position={Object {}}
- selectedTags={
- Array [
- "mytag",
- ]
- }
- tags={
- Array [
- "test",
- "second",
- ]
- }
-/>
+<DropdownOverlay
+ placement="bottom-right"
+>
+ <TagsSelector
+ listSize={10}
+ onSearch={[Function]}
+ onSelect={[Function]}
+ onUnselect={[Function]}
+ selectedTags={
+ Array [
+ "mytag",
+ ]
+ }
+ tags={
+ Array [
+ "test",
+ "second",
+ ]
+ }
+ />
+</DropdownOverlay>
`;
diff --git a/server/sonar-web/src/main/js/components/issue/popups/__tests__/__snapshots__/SetSeverityPopup-test.js.snap b/server/sonar-web/src/main/js/components/issue/popups/__tests__/__snapshots__/SetSeverityPopup-test.js.snap
index f5cc9cfed81..f8818f53cab 100644
--- a/server/sonar-web/src/main/js/components/issue/popups/__tests__/__snapshots__/SetSeverityPopup-test.js.snap
+++ b/server/sonar-web/src/main/js/components/issue/popups/__tests__/__snapshots__/SetSeverityPopup-test.js.snap
@@ -1,9 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`should render tags popup correctly 1`] = `
-<BubblePopup
- customClass="bubble-popup-menu bubble-popup-bottom"
->
+<DropdownOverlay>
<SelectList
currentItem="MAJOR"
items={
@@ -68,5 +66,5 @@ exports[`should render tags popup correctly 1`] = `
severity.INFO
</SelectListItem>
</SelectList>
-</BubblePopup>
+</DropdownOverlay>
`;
diff --git a/server/sonar-web/src/main/js/components/issue/popups/__tests__/__snapshots__/SetTransitionPopup-test.js.snap b/server/sonar-web/src/main/js/components/issue/popups/__tests__/__snapshots__/SetTransitionPopup-test.js.snap
index 2b0be175cbe..a9728b1687a 100644
--- a/server/sonar-web/src/main/js/components/issue/popups/__tests__/__snapshots__/SetTransitionPopup-test.js.snap
+++ b/server/sonar-web/src/main/js/components/issue/popups/__tests__/__snapshots__/SetTransitionPopup-test.js.snap
@@ -1,9 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`should render tags popup correctly 1`] = `
-<BubblePopup
- customClass="bubble-popup-menu bubble-popup-bottom"
->
+<DropdownOverlay>
<SelectList
currentItem="confirm"
items={
@@ -45,5 +43,5 @@ exports[`should render tags popup correctly 1`] = `
issue.transition.wontfix
</SelectListItem>
</SelectList>
-</BubblePopup>
+</DropdownOverlay>
`;
diff --git a/server/sonar-web/src/main/js/components/issue/popups/__tests__/__snapshots__/SetTypePopup-test.js.snap b/server/sonar-web/src/main/js/components/issue/popups/__tests__/__snapshots__/SetTypePopup-test.js.snap
index 190d91cb61b..5055d807449 100644
--- a/server/sonar-web/src/main/js/components/issue/popups/__tests__/__snapshots__/SetTypePopup-test.js.snap
+++ b/server/sonar-web/src/main/js/components/issue/popups/__tests__/__snapshots__/SetTypePopup-test.js.snap
@@ -1,9 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`should render tags popup correctly 1`] = `
-<BubblePopup
- customClass="bubble-popup-menu bubble-popup-bottom"
->
+<DropdownOverlay>
<SelectList
currentItem="BUG"
items={
@@ -46,5 +44,5 @@ exports[`should render tags popup correctly 1`] = `
issue.type.CODE_SMELL
</SelectListItem>
</SelectList>
-</BubblePopup>
+</DropdownOverlay>
`;