aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/src/main/js/apps/organizations
diff options
context:
space:
mode:
authorStas Vilchik <stas.vilchik@sonarsource.com>2017-10-31 16:26:09 +0100
committerStas Vilchik <stas.vilchik@sonarsource.com>2017-11-03 14:28:18 +0100
commit20a70acea9fad007677c6e5ba28b99a6a7b532cc (patch)
tree5748fbe5568d81c5f8f0ac72ccbd6cea75d3093e /server/sonar-web/src/main/js/apps/organizations
parentee2fab297a68aaebcdcb3b71b1fc49f2f89a5d46 (diff)
downloadsonarqube-20a70acea9fad007677c6e5ba28b99a6a7b532cc.tar.gz
sonarqube-20a70acea9fad007677c6e5ba28b99a6a7b532cc.zip
SONAR-10022 Grouping actions must be consistent
Diffstat (limited to 'server/sonar-web/src/main/js/apps/organizations')
-rw-r--r--server/sonar-web/src/main/js/apps/organizations/components/MembersListItem.js43
-rw-r--r--server/sonar-web/src/main/js/apps/organizations/components/__tests__/__snapshots__/MembersListItem-test.js.snap198
-rw-r--r--server/sonar-web/src/main/js/apps/organizations/components/forms/ManageMemberGroupsForm.js32
-rw-r--r--server/sonar-web/src/main/js/apps/organizations/components/forms/RemoveMemberForm.js8
-rw-r--r--server/sonar-web/src/main/js/apps/organizations/components/forms/__tests__/ManageMemberGroupsForm-test.js2
-rw-r--r--server/sonar-web/src/main/js/apps/organizations/components/forms/__tests__/RemoveMemberForm-test.js2
-rw-r--r--server/sonar-web/src/main/js/apps/organizations/components/forms/__tests__/__snapshots__/ManageMemberGroupsForm-test.js.snap11
-rw-r--r--server/sonar-web/src/main/js/apps/organizations/components/forms/__tests__/__snapshots__/RemoveMemberForm-test.js.snap13
8 files changed, 128 insertions, 181 deletions
diff --git a/server/sonar-web/src/main/js/apps/organizations/components/MembersListItem.js b/server/sonar-web/src/main/js/apps/organizations/components/MembersListItem.js
index 7c5c784dfd6..1147d0239be 100644
--- a/server/sonar-web/src/main/js/apps/organizations/components/MembersListItem.js
+++ b/server/sonar-web/src/main/js/apps/organizations/components/MembersListItem.js
@@ -24,7 +24,9 @@ import { translateWithParameters } from '../../../helpers/l10n';
import { formatMeasure } from '../../../helpers/measures';
import RemoveMemberForm from './forms/RemoveMemberForm';
import ManageMemberGroupsForm from './forms/ManageMemberGroupsForm';
-import SettingsIcon from '../../../components/icons-components/SettingsIcon';
+import ActionsDropdown, {
+ ActionsDropdownDivider
+} from '../../../components/controls/ActionsDropdown';
/*:: import type { Member } from '../../../store/organizationsMembers/actions'; */
/*:: import type { Organization, OrgGroup } from '../../../store/organizations/duck'; */
@@ -64,31 +66,20 @@ export default class MembersListItem extends React.PureComponent {
)}
{organization.canAdmin && (
<td className="nowrap text-middle text-right">
- <div className="dropdown">
- <button
- className="dropdown-toggle little-spacer-right button-compact"
- data-toggle="dropdown">
- <SettingsIcon style={{ marginTop: 4 }} /> <i className="icon-dropdown" />
- </button>
- <ul className="dropdown-menu dropdown-menu-right">
- <li>
- <ManageMemberGroupsForm
- organizationGroups={this.props.organizationGroups}
- organization={this.props.organization}
- updateMemberGroups={this.props.updateMemberGroups}
- member={this.props.member}
- />
- </li>
- <li role="separator" className="divider" />
- <li>
- <RemoveMemberForm
- organization={this.props.organization}
- removeMember={this.props.removeMember}
- member={this.props.member}
- />
- </li>
- </ul>
- </div>
+ <ActionsDropdown>
+ <ManageMemberGroupsForm
+ organizationGroups={this.props.organizationGroups}
+ organization={this.props.organization}
+ updateMemberGroups={this.props.updateMemberGroups}
+ member={this.props.member}
+ />
+ <ActionsDropdownDivider />
+ <RemoveMemberForm
+ organization={this.props.organization}
+ removeMember={this.props.removeMember}
+ member={this.props.member}
+ />
+ </ActionsDropdown>
</td>
)}
</tr>
diff --git a/server/sonar-web/src/main/js/apps/organizations/components/__tests__/__snapshots__/MembersListItem-test.js.snap b/server/sonar-web/src/main/js/apps/organizations/components/__tests__/__snapshots__/MembersListItem-test.js.snap
index 0bfde40983a..b88cbc6b739 100644
--- a/server/sonar-web/src/main/js/apps/organizations/components/__tests__/__snapshots__/MembersListItem-test.js.snap
+++ b/server/sonar-web/src/main/js/apps/organizations/components/__tests__/__snapshots__/MembersListItem-test.js.snap
@@ -31,70 +31,41 @@ exports[`should groups at 0 if the groupCount field is not defined (just added u
<td
className="nowrap text-middle text-right"
>
- <div
- className="dropdown"
- >
- <button
- className="dropdown-toggle little-spacer-right button-compact"
- data-toggle="dropdown"
- >
- <SettingsIcon
- style={
- Object {
- "marginTop": 4,
- }
+ <ActionsDropdown>
+ <ManageMemberGroupsForm
+ member={
+ Object {
+ "avatar": "7daf6c79d4802916d83f6266e24850af",
+ "login": "john",
+ "name": "John Doe",
+ }
+ }
+ organization={
+ Object {
+ "canAdmin": true,
+ "key": "foo",
+ "name": "Foo",
+ }
+ }
+ />
+ <ActionsDropdownDivider />
+ <RemoveMemberForm
+ member={
+ Object {
+ "avatar": "7daf6c79d4802916d83f6266e24850af",
+ "login": "john",
+ "name": "John Doe",
+ }
+ }
+ organization={
+ Object {
+ "canAdmin": true,
+ "key": "foo",
+ "name": "Foo",
}
- />
-
- <i
- className="icon-dropdown"
- />
- </button>
- <ul
- className="dropdown-menu dropdown-menu-right"
- >
- <li>
- <ManageMemberGroupsForm
- member={
- Object {
- "avatar": "7daf6c79d4802916d83f6266e24850af",
- "login": "john",
- "name": "John Doe",
- }
- }
- organization={
- Object {
- "canAdmin": true,
- "key": "foo",
- "name": "Foo",
- }
- }
- />
- </li>
- <li
- className="divider"
- role="separator"
- />
- <li>
- <RemoveMemberForm
- member={
- Object {
- "avatar": "7daf6c79d4802916d83f6266e24850af",
- "login": "john",
- "name": "John Doe",
- }
- }
- organization={
- Object {
- "canAdmin": true,
- "key": "foo",
- "name": "Foo",
- }
- }
- />
- </li>
- </ul>
- </div>
+ }
+ />
+ </ActionsDropdown>
</td>
</tr>
`;
@@ -156,72 +127,43 @@ exports[`should render actions and groups for admin 1`] = `
<td
className="nowrap text-middle text-right"
>
- <div
- className="dropdown"
- >
- <button
- className="dropdown-toggle little-spacer-right button-compact"
- data-toggle="dropdown"
- >
- <SettingsIcon
- style={
- Object {
- "marginTop": 4,
- }
+ <ActionsDropdown>
+ <ManageMemberGroupsForm
+ member={
+ Object {
+ "avatar": "",
+ "groupCount": 3,
+ "login": "admin",
+ "name": "Admin Istrator",
+ }
+ }
+ organization={
+ Object {
+ "canAdmin": true,
+ "key": "foo",
+ "name": "Foo",
+ }
+ }
+ />
+ <ActionsDropdownDivider />
+ <RemoveMemberForm
+ member={
+ Object {
+ "avatar": "",
+ "groupCount": 3,
+ "login": "admin",
+ "name": "Admin Istrator",
+ }
+ }
+ organization={
+ Object {
+ "canAdmin": true,
+ "key": "foo",
+ "name": "Foo",
}
- />
-
- <i
- className="icon-dropdown"
- />
- </button>
- <ul
- className="dropdown-menu dropdown-menu-right"
- >
- <li>
- <ManageMemberGroupsForm
- member={
- Object {
- "avatar": "",
- "groupCount": 3,
- "login": "admin",
- "name": "Admin Istrator",
- }
- }
- organization={
- Object {
- "canAdmin": true,
- "key": "foo",
- "name": "Foo",
- }
- }
- />
- </li>
- <li
- className="divider"
- role="separator"
- />
- <li>
- <RemoveMemberForm
- member={
- Object {
- "avatar": "",
- "groupCount": 3,
- "login": "admin",
- "name": "Admin Istrator",
- }
- }
- organization={
- Object {
- "canAdmin": true,
- "key": "foo",
- "name": "Foo",
- }
- }
- />
- </li>
- </ul>
- </div>
+ }
+ />
+ </ActionsDropdown>
</td>
</tr>
`;
diff --git a/server/sonar-web/src/main/js/apps/organizations/components/forms/ManageMemberGroupsForm.js b/server/sonar-web/src/main/js/apps/organizations/components/forms/ManageMemberGroupsForm.js
index 6e8818b6e85..58f6838bc5d 100644
--- a/server/sonar-web/src/main/js/apps/organizations/components/forms/ManageMemberGroupsForm.js
+++ b/server/sonar-web/src/main/js/apps/organizations/components/forms/ManageMemberGroupsForm.js
@@ -24,6 +24,7 @@ import { getUserGroups } from '../../../../api/users';
import Modal from '../../../../components/controls/Modal';
import { translate, translateWithParameters } from '../../../../helpers/l10n';
import OrganizationGroupCheckbox from '../OrganizationGroupCheckbox';
+import { ActionsDropdownItem } from '../../../../components/controls/ActionsDropdown';
/*:: import type { Member } from '../../../../store/organizationsMembers/actions'; */
/*:: import type { Organization, OrgGroup } from '../../../../store/organizations/duck'; */
@@ -45,14 +46,22 @@ type State = {
*/
export default class ManageMemberGroupsForm extends React.PureComponent {
+ /*:: mounted: boolean */
/*:: props: Props; */
state /*: State */ = {
open: false
};
- openForm = (evt /*: MouseEvent */) => {
- evt.preventDefault();
+ componentDidMount() {
+ this.mounted = true;
+ }
+
+ componentWillUnmount() {
+ this.mounted = false;
+ }
+
+ openForm = () => {
this.loadUserGroups();
this.setState({ open: true });
};
@@ -63,9 +72,18 @@ export default class ManageMemberGroupsForm extends React.PureComponent {
loadUserGroups = () => {
this.setState({ loading: true });
- getUserGroups(this.props.member.login, this.props.organization.key).then(response => {
- this.setState({ loading: false, userGroups: keyBy(response.groups, 'name') });
- });
+ getUserGroups(this.props.member.login, this.props.organization.key).then(
+ response => {
+ if (this.mounted) {
+ this.setState({ loading: false, userGroups: keyBy(response.groups, 'name') });
+ }
+ },
+ () => {
+ if (this.mounted) {
+ this.setState({ loading: false });
+ }
+ }
+ );
};
isGroupSelected = (groupName /*: string */) => {
@@ -148,9 +166,9 @@ export default class ManageMemberGroupsForm extends React.PureComponent {
render() {
const buttonComponent = (
- <a key="manage-member-button" onClick={this.openForm} href="#">
+ <ActionsDropdownItem onClick={this.openForm}>
{translate('organization.members.manage_groups')}
- </a>
+ </ActionsDropdownItem>
);
if (this.state.open) {
return [buttonComponent, this.renderModal()];
diff --git a/server/sonar-web/src/main/js/apps/organizations/components/forms/RemoveMemberForm.js b/server/sonar-web/src/main/js/apps/organizations/components/forms/RemoveMemberForm.js
index 94fb72dd24f..9a0db75be63 100644
--- a/server/sonar-web/src/main/js/apps/organizations/components/forms/RemoveMemberForm.js
+++ b/server/sonar-web/src/main/js/apps/organizations/components/forms/RemoveMemberForm.js
@@ -20,6 +20,7 @@
// @flow
import React from 'react';
import Modal from '../../../../components/controls/Modal';
+import { ActionsDropdownItem } from '../../../../components/controls/ActionsDropdown';
import { translate, translateWithParameters } from '../../../../helpers/l10n';
/*:: import type { Member } from '../../../../store/organizationsMembers/actions'; */
/*:: import type { Organization } from '../../../../store/organizations/duck'; */
@@ -45,8 +46,7 @@ export default class RemoveMemberForm extends React.PureComponent {
open: false
};
- openForm = (evt /*: MouseEvent */) => {
- evt.preventDefault();
+ openForm = () => {
this.setState({ open: true });
};
@@ -94,9 +94,9 @@ export default class RemoveMemberForm extends React.PureComponent {
render() {
const buttonComponent = (
- <a key="remove-member-button" onClick={this.openForm} href="#">
+ <ActionsDropdownItem destructive={true} onClick={this.openForm}>
{translate('organization.members.remove')}
- </a>
+ </ActionsDropdownItem>
);
if (this.state.open) {
return [buttonComponent, this.renderModal()];
diff --git a/server/sonar-web/src/main/js/apps/organizations/components/forms/__tests__/ManageMemberGroupsForm-test.js b/server/sonar-web/src/main/js/apps/organizations/components/forms/__tests__/ManageMemberGroupsForm-test.js
index c28b5cbcd9a..63503e40918 100644
--- a/server/sonar-web/src/main/js/apps/organizations/components/forms/__tests__/ManageMemberGroupsForm-test.js
+++ b/server/sonar-web/src/main/js/apps/organizations/components/forms/__tests__/ManageMemberGroupsForm-test.js
@@ -82,7 +82,7 @@ it('should render and open the modal', () => {
it('should correctly handle user interactions', () => {
const form = getMountedForm();
- click(form.wrapper.find('a'));
+ form.wrapper.find('ActionsDropdownItem').prop('onClick')();
expect(form.wrapper.state('open')).toBeTruthy();
expect(form.instance.loadUserGroups).toBeCalled();
expect(form.wrapper.state()).toMatchSnapshot();
diff --git a/server/sonar-web/src/main/js/apps/organizations/components/forms/__tests__/RemoveMemberForm-test.js b/server/sonar-web/src/main/js/apps/organizations/components/forms/__tests__/RemoveMemberForm-test.js
index 5c007ae4123..0fee4e72b58 100644
--- a/server/sonar-web/src/main/js/apps/organizations/components/forms/__tests__/RemoveMemberForm-test.js
+++ b/server/sonar-web/src/main/js/apps/organizations/components/forms/__tests__/RemoveMemberForm-test.js
@@ -42,7 +42,7 @@ it('should correctly handle user interactions', () => {
<RemoveMemberForm member={member} removeMember={removeMember} organization={organization} />
);
const instance = wrapper.instance();
- click(wrapper.find('a'));
+ wrapper.find('ActionsDropdownItem').prop('onClick')();
expect(wrapper.state('open')).toBeTruthy();
instance.handleSubmit(mockEvent);
expect(removeMember.mock.calls).toMatchSnapshot();
diff --git a/server/sonar-web/src/main/js/apps/organizations/components/forms/__tests__/__snapshots__/ManageMemberGroupsForm-test.js.snap b/server/sonar-web/src/main/js/apps/organizations/components/forms/__tests__/__snapshots__/ManageMemberGroupsForm-test.js.snap
index 51d9f708ee7..94ff9bb6705 100644
--- a/server/sonar-web/src/main/js/apps/organizations/components/forms/__tests__/__snapshots__/ManageMemberGroupsForm-test.js.snap
+++ b/server/sonar-web/src/main/js/apps/organizations/components/forms/__tests__/__snapshots__/ManageMemberGroupsForm-test.js.snap
@@ -69,23 +69,20 @@ Object {
`;
exports[`should render and open the modal 1`] = `
-<a
- href="#"
- key="manage-member-button"
+<ActionsDropdownItem
onClick={[Function]}
>
organization.members.manage_groups
-</a>
+</ActionsDropdownItem>
`;
exports[`should render and open the modal 2`] = `
Array [
- <a
- href="#"
+ <ActionsDropdownItem
onClick={[Function]}
>
organization.members.manage_groups
- </a>,
+ </ActionsDropdownItem>,
<Modal
contentLabel="organization.members.manage_groups"
onRequestClose={[Function]}
diff --git a/server/sonar-web/src/main/js/apps/organizations/components/forms/__tests__/__snapshots__/RemoveMemberForm-test.js.snap b/server/sonar-web/src/main/js/apps/organizations/components/forms/__tests__/__snapshots__/RemoveMemberForm-test.js.snap
index 3e362fcf4db..861e8d98f02 100644
--- a/server/sonar-web/src/main/js/apps/organizations/components/forms/__tests__/__snapshots__/RemoveMemberForm-test.js.snap
+++ b/server/sonar-web/src/main/js/apps/organizations/components/forms/__tests__/__snapshots__/RemoveMemberForm-test.js.snap
@@ -14,23 +14,22 @@ Array [
`;
exports[`should render and open the modal 1`] = `
-<a
- href="#"
- key="remove-member-button"
+<ActionsDropdownItem
+ destructive={true}
onClick={[Function]}
>
organization.members.remove
-</a>
+</ActionsDropdownItem>
`;
exports[`should render and open the modal 2`] = `
Array [
- <a
- href="#"
+ <ActionsDropdownItem
+ destructive={true}
onClick={[Function]}
>
organization.members.remove
- </a>,
+ </ActionsDropdownItem>,
<Modal
contentLabel="users.remove"
onRequestClose={[Function]}