diff options
author | Grégoire Aubert <gregoire.aubert@sonarsource.com> | 2017-04-26 15:41:47 +0200 |
---|---|---|
committer | Grégoire Aubert <gregaubert@users.noreply.github.com> | 2017-05-01 16:26:31 +0200 |
commit | 61da4f3531f26c70abc767cc3f584effcbfe0576 (patch) | |
tree | e89a276372e6304e795630facac262ea5ede8133 /server | |
parent | a194043a66e5ac190072489d2a18926504017f87 (diff) | |
download | sonarqube-61da4f3531f26c70abc767cc3f584effcbfe0576.tar.gz sonarqube-61da4f3531f26c70abc767cc3f584effcbfe0576.zip |
SONAR-8992 Fix members add form, show only non members
Diffstat (limited to 'server')
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> |