aboutsummaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorGrégoire Aubert <gregoire.aubert@sonarsource.com>2017-04-26 15:41:47 +0200
committerGrégoire Aubert <gregaubert@users.noreply.github.com>2017-05-01 16:26:31 +0200
commit61da4f3531f26c70abc767cc3f584effcbfe0576 (patch)
treee89a276372e6304e795630facac262ea5ede8133 /server
parenta194043a66e5ac190072489d2a18926504017f87 (diff)
downloadsonarqube-61da4f3531f26c70abc767cc3f584effcbfe0576.tar.gz
sonarqube-61da4f3531f26c70abc767cc3f584effcbfe0576.zip
SONAR-8992 Fix members add form, show only non members
Diffstat (limited to 'server')
-rw-r--r--server/sonar-web/src/main/js/apps/organizations/components/OrganizationMembers.js6
-rw-r--r--server/sonar-web/src/main/js/apps/organizations/components/__tests__/__snapshots__/MembersListItem-test.js.snap104
-rw-r--r--server/sonar-web/src/main/js/apps/organizations/components/__tests__/__snapshots__/OrganizationMembers-test.js.snap7
-rw-r--r--server/sonar-web/src/main/js/apps/organizations/components/forms/AddMemberForm.js18
-rw-r--r--server/sonar-web/src/main/js/apps/users/components/UsersSelectSearch.js23
-rw-r--r--server/sonar-web/src/main/js/apps/users/components/UsersSelectSearchValue.js4
-rw-r--r--server/sonar-web/src/main/js/apps/users/components/__tests__/__snapshots__/UsersSelectSearchOption-test.js.snap36
-rw-r--r--server/sonar-web/src/main/js/apps/users/components/__tests__/__snapshots__/UsersSelectSearchValue-test.js.snap8
8 files changed, 144 insertions, 62 deletions
diff --git a/server/sonar-web/src/main/js/apps/organizations/components/OrganizationMembers.js b/server/sonar-web/src/main/js/apps/organizations/components/OrganizationMembers.js
index 49eac0e3fa7..c4e3f6bcd25 100644
--- a/server/sonar-web/src/main/js/apps/organizations/components/OrganizationMembers.js
+++ b/server/sonar-web/src/main/js/apps/organizations/components/OrganizationMembers.js
@@ -84,7 +84,11 @@ export default class OrganizationMembers extends React.PureComponent {
{organization.canAdmin &&
<div className="page-actions">
<div className="button-group">
- <AddMemberForm memberLogins={this.props.memberLogins} addMember={this.addMember} />
+ <AddMemberForm
+ addMember={this.addMember}
+ organization={organization}
+ memberLogins={this.props.memberLogins}
+ />
</div>
</div>}
</MembersPageHeader>
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 153c98f4d35..7d5d1fd90e6 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
@@ -1,40 +1,53 @@
-exports[`test should groups at 0 if the groupCount field is not defined (just added user) 1`] = `
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should groups at 0 if the groupCount field is not defined (just added user) 1`] = `
<tr>
<td
- className="thin nowrap">
+ className="thin nowrap"
+ >
<Connect(Avatar)
hash="7daf6c79d4802916d83f6266e24850af"
- size={36} />
+ size={36}
+ />
</td>
<td
- className="nowrap text-middle">
+ className="nowrap text-middle"
+ >
<strong>
John Doe
</strong>
<span
- className="note little-spacer-left">
+ className="note little-spacer-left"
+ >
john
</span>
</td>
<td
- className="text-right text-middle">
+ className="text-right text-middle"
+ >
organization.members.x_groups.0
</td>
<td
- className="nowrap text-middle text-right">
+ className="nowrap text-middle text-right"
+ >
<div
- className="dropdown">
+ className="dropdown"
+ >
<button
className="dropdown-toggle little-spacer-right"
- data-toggle="dropdown">
+ data-toggle="dropdown"
+ >
<i
- className="icon-settings" />
+ className="icon-settings"
+ />
<i
- className="icon-dropdown" />
+ className="icon-dropdown"
+ />
</button>
<ul
- className="dropdown-menu dropdown-menu-right">
+ className="dropdown-menu dropdown-menu-right"
+ >
<li>
<ManageMemberGroupsForm
member={
@@ -50,11 +63,13 @@ exports[`test should groups at 0 if the groupCount field is not defined (just ad
"key": "foo",
"name": "Foo",
}
- } />
+ }
+ />
</li>
<li
className="divider"
- role="separator" />
+ role="separator"
+ />
<li>
<RemoveMemberForm
member={
@@ -70,7 +85,8 @@ exports[`test should groups at 0 if the groupCount field is not defined (just ad
"key": "foo",
"name": "Foo",
}
- } />
+ }
+ />
</li>
</ul>
</div>
@@ -78,64 +94,79 @@ exports[`test should groups at 0 if the groupCount field is not defined (just ad
</tr>
`;
-exports[`test should not render actions and groups for non admin 1`] = `
+exports[`should not render actions and groups for non admin 1`] = `
<tr>
<td
- className="thin nowrap">
+ className="thin nowrap"
+ >
<Connect(Avatar)
hash=""
- size={36} />
+ size={36}
+ />
</td>
<td
- className="nowrap text-middle">
+ className="nowrap text-middle"
+ >
<strong>
Admin Istrator
</strong>
<span
- className="note little-spacer-left">
+ className="note little-spacer-left"
+ >
admin
</span>
</td>
</tr>
`;
-exports[`test should render actions and groups for admin 1`] = `
+exports[`should render actions and groups for admin 1`] = `
<tr>
<td
- className="thin nowrap">
+ className="thin nowrap"
+ >
<Connect(Avatar)
hash=""
- size={36} />
+ size={36}
+ />
</td>
<td
- className="nowrap text-middle">
+ className="nowrap text-middle"
+ >
<strong>
Admin Istrator
</strong>
<span
- className="note little-spacer-left">
+ className="note little-spacer-left"
+ >
admin
</span>
</td>
<td
- className="text-right text-middle">
+ className="text-right text-middle"
+ >
organization.members.x_groups.3
</td>
<td
- className="nowrap text-middle text-right">
+ className="nowrap text-middle text-right"
+ >
<div
- className="dropdown">
+ className="dropdown"
+ >
<button
className="dropdown-toggle little-spacer-right"
- data-toggle="dropdown">
+ data-toggle="dropdown"
+ >
<i
- className="icon-settings" />
+ className="icon-settings"
+ />
<i
- className="icon-dropdown" />
+ className="icon-dropdown"
+ />
</button>
<ul
- className="dropdown-menu dropdown-menu-right">
+ className="dropdown-menu dropdown-menu-right"
+ >
<li>
<ManageMemberGroupsForm
member={
@@ -152,11 +183,13 @@ exports[`test should render actions and groups for admin 1`] = `
"key": "foo",
"name": "Foo",
}
- } />
+ }
+ />
</li>
<li
className="divider"
- role="separator" />
+ role="separator"
+ />
<li>
<RemoveMemberForm
member={
@@ -173,7 +206,8 @@ exports[`test should render actions and groups for admin 1`] = `
"key": "foo",
"name": "Foo",
}
- } />
+ }
+ />
</li>
</ul>
</div>
diff --git a/server/sonar-web/src/main/js/apps/organizations/components/__tests__/__snapshots__/OrganizationMembers-test.js.snap b/server/sonar-web/src/main/js/apps/organizations/components/__tests__/__snapshots__/OrganizationMembers-test.js.snap
index 4c3bdede556..f6da626a33f 100644
--- a/server/sonar-web/src/main/js/apps/organizations/components/__tests__/__snapshots__/OrganizationMembers-test.js.snap
+++ b/server/sonar-web/src/main/js/apps/organizations/components/__tests__/__snapshots__/OrganizationMembers-test.js.snap
@@ -62,6 +62,13 @@ exports[`should render actions for admin 1`] = `
>
<AddMemberForm
addMember={[Function]}
+ organization={
+ Object {
+ "canAdmin": true,
+ "key": "foo",
+ "name": "Foo",
+ }
+ }
/>
</div>
</div>
diff --git a/server/sonar-web/src/main/js/apps/organizations/components/forms/AddMemberForm.js b/server/sonar-web/src/main/js/apps/organizations/components/forms/AddMemberForm.js
index f1fafe1a2e0..4502597be29 100644
--- a/server/sonar-web/src/main/js/apps/organizations/components/forms/AddMemberForm.js
+++ b/server/sonar-web/src/main/js/apps/organizations/components/forms/AddMemberForm.js
@@ -21,13 +21,15 @@
import React from 'react';
import Modal from 'react-modal';
import UsersSelectSearch from '../../../users/components/UsersSelectSearch';
-import { searchUsers } from '../../../../api/users';
+import { searchMembers } from '../../../../api/organizations';
import { translate } from '../../../../helpers/l10n';
+import type { Organization } from '../../../../store/organizations/duck';
import type { Member } from '../../../../store/organizationsMembers/actions';
type Props = {
- memberLogins: Array<string>,
- addMember: (member: Member) => void
+ addMember: (member: Member) => void,
+ organization: Organization,
+ memberLogins: Array<string>
};
type State = {
@@ -50,6 +52,14 @@ export default class AddMemberForm extends React.PureComponent {
this.setState({ open: false, selectedMember: undefined });
};
+ handleSearch = (query?: string, ps: number): Promise<*> => {
+ const data = { organization: this.props.organization.key, ps, selected: 'deselected' };
+ if (!query) {
+ return searchMembers(data);
+ }
+ return searchMembers({ ...data, q: query });
+ };
+
handleSubmit = (e: Object) => {
e.preventDefault();
if (this.state.selectedMember) {
@@ -81,7 +91,7 @@ export default class AddMemberForm extends React.PureComponent {
autoFocus={true}
selectedUser={this.state.selectedMember}
excludedUsers={this.props.memberLogins}
- searchUsers={searchUsers}
+ searchUsers={this.handleSearch}
handleValueChange={this.selectedMemberChange}
/>
</div>
diff --git a/server/sonar-web/src/main/js/apps/users/components/UsersSelectSearch.js b/server/sonar-web/src/main/js/apps/users/components/UsersSelectSearch.js
index 007a6e05138..f6a9b1ad5ee 100644
--- a/server/sonar-web/src/main/js/apps/users/components/UsersSelectSearch.js
+++ b/server/sonar-web/src/main/js/apps/users/components/UsersSelectSearch.js
@@ -51,6 +51,7 @@ type State = {
const LIST_SIZE = 10;
export default class UsersSelectSearch extends React.PureComponent {
+ mounted: boolean;
props: Props;
state: State;
@@ -59,8 +60,8 @@ export default class UsersSelectSearch extends React.PureComponent {
this.handleSearch = debounce(this.handleSearch, 250);
this.state = { searchResult: [], isLoading: false, search: '' };
}
-
componentDidMount() {
+ this.mounted = true;
this.handleSearch(this.state.search);
}
@@ -70,19 +71,33 @@ export default class UsersSelectSearch extends React.PureComponent {
}
}
+ componentWillUnmount() {
+ this.mounted = false;
+ }
+
filterSearchResult = ({ users }: { users: Array<Option> }) =>
users.filter(user => !this.props.excludedUsers.includes(user.login)).slice(0, LIST_SIZE);
handleSearch = (search: string) => {
- this.setState({ isLoading: true, search });
this.props
.searchUsers(search, Math.min(this.props.excludedUsers.length + LIST_SIZE, 500))
.then(this.filterSearchResult)
.then(searchResult => {
- this.setState({ isLoading: false, searchResult });
+ if (this.mounted) {
+ this.setState({ isLoading: false, searchResult });
+ }
});
};
+ handleInputChange = (search: string) => {
+ if (search == null || search.length === 1) {
+ this.setState({ search });
+ } else {
+ this.setState({ isLoading: true, search });
+ this.handleSearch(search);
+ }
+ };
+
render() {
const noResult = this.state.search.length === 1
? translateWithParameters('select2.tooShort', 2)
@@ -96,7 +111,7 @@ export default class UsersSelectSearch extends React.PureComponent {
optionComponent={UsersSelectSearchOption}
valueComponent={UsersSelectSearchValue}
onChange={this.props.handleValueChange}
- onInputChange={this.handleSearch}
+ onInputChange={this.handleInputChange}
value={this.props.selectedUser}
placeholder=""
noResultsText={noResult}
diff --git a/server/sonar-web/src/main/js/apps/users/components/UsersSelectSearchValue.js b/server/sonar-web/src/main/js/apps/users/components/UsersSelectSearchValue.js
index 915817227dd..19ad6ab9029 100644
--- a/server/sonar-web/src/main/js/apps/users/components/UsersSelectSearchValue.js
+++ b/server/sonar-web/src/main/js/apps/users/components/UsersSelectSearchValue.js
@@ -40,8 +40,8 @@ export default class UsersSelectSearchValue extends React.PureComponent {
user.login &&
<div className="Select-value-label">
<Avatar hash={user.avatar} email={user.email} size={AVATAR_SIZE} />
- <strong className="spacer-left">{user.login}</strong>
- <span className="note little-spacer-left">{this.props.children}</span>
+ <strong className="spacer-left">{this.props.children}</strong>
+ <span className="note little-spacer-left">{user.login}</span>
</div>}
</div>
);
diff --git a/server/sonar-web/src/main/js/apps/users/components/__tests__/__snapshots__/UsersSelectSearchOption-test.js.snap b/server/sonar-web/src/main/js/apps/users/components/__tests__/__snapshots__/UsersSelectSearchOption-test.js.snap
index 9ee1a0b7206..45aa90aba39 100644
--- a/server/sonar-web/src/main/js/apps/users/components/__tests__/__snapshots__/UsersSelectSearchOption-test.js.snap
+++ b/server/sonar-web/src/main/js/apps/users/components/__tests__/__snapshots__/UsersSelectSearchOption-test.js.snap
@@ -1,43 +1,55 @@
-exports[`test should render correctly with email instead of hash 1`] = `
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should render correctly with email instead of hash 1`] = `
<div
onMouseDown={[Function]}
onMouseEnter={[Function]}
onMouseMove={[Function]}
- title="Administrator">
+ title="Administrator"
+>
<div
- className="little-spacer-bottom little-spacer-top">
+ className="little-spacer-bottom little-spacer-top"
+ >
<Connect(Avatar)
email="admin@admin.ch"
- size={20} />
+ size={20}
+ />
<strong
- className="spacer-left">
+ className="spacer-left"
+ >
Administrator
</strong>
<span
- className="note little-spacer-left">
+ className="note little-spacer-left"
+ >
admin
</span>
</div>
</div>
`;
-exports[`test should render correctly without all parameters 1`] = `
+exports[`should render correctly without all parameters 1`] = `
<div
onMouseDown={[Function]}
onMouseEnter={[Function]}
onMouseMove={[Function]}
- title="Administrator">
+ title="Administrator"
+>
<div
- className="little-spacer-bottom little-spacer-top">
+ className="little-spacer-bottom little-spacer-top"
+ >
<Connect(Avatar)
hash="7daf6c79d4802916d83f6266e24850af"
- size={20} />
+ size={20}
+ />
<strong
- className="spacer-left">
+ className="spacer-left"
+ >
Administrator
</strong>
<span
- className="note little-spacer-left">
+ className="note little-spacer-left"
+ >
admin
</span>
</div>
diff --git a/server/sonar-web/src/main/js/apps/users/components/__tests__/__snapshots__/UsersSelectSearchValue-test.js.snap b/server/sonar-web/src/main/js/apps/users/components/__tests__/__snapshots__/UsersSelectSearchValue-test.js.snap
index c2c7daf8247..e6523c5d2e6 100644
--- a/server/sonar-web/src/main/js/apps/users/components/__tests__/__snapshots__/UsersSelectSearchValue-test.js.snap
+++ b/server/sonar-web/src/main/js/apps/users/components/__tests__/__snapshots__/UsersSelectSearchValue-test.js.snap
@@ -15,12 +15,12 @@ exports[`should render correctly with a user 1`] = `
<strong
className="spacer-left"
>
- admin
+ Administrator
</strong>
<span
className="note little-spacer-left"
>
- Administrator
+ admin
</span>
</div>
</div>
@@ -41,12 +41,12 @@ exports[`should render correctly with email instead of hash 1`] = `
<strong
className="spacer-left"
>
- admin
+ Administrator
</strong>
<span
className="note little-spacer-left"
>
- Administrator
+ admin
</span>
</div>
</div>