From: Grégoire Aubert Date: Thu, 13 Apr 2017 10:00:23 +0000 (+0200) Subject: SONAR-8994 Fix groups management for non default org X-Git-Tag: 6.4-RC1~383 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=20893897816c27918c0c8e03c7ec8351c1fdc30c;p=sonarqube.git SONAR-8994 Fix groups management for non default org --- diff --git a/it/it-tests/src/test/java/it/organization/OrganizationMembershipTest.java b/it/it-tests/src/test/java/it/organization/OrganizationMembershipTest.java index 4f6dbe6cc15..0b05b0ef264 100644 --- a/it/it-tests/src/test/java/it/organization/OrganizationMembershipTest.java +++ b/it/it-tests/src/test/java/it/organization/OrganizationMembershipTest.java @@ -223,7 +223,6 @@ public class OrganizationMembershipTest { } @Test - @Ignore("To be fixed by SONAR-8994") public void admin_can_manage_groups() { String orgKey = createOrganization(); userRule.createUser("foo", "pwd"); diff --git a/server/sonar-web/src/main/js/api/user_groups.js b/server/sonar-web/src/main/js/api/user_groups.js index becfdb9c8a0..de515f119b0 100644 --- a/server/sonar-web/src/main/js/api/user_groups.js +++ b/server/sonar-web/src/main/js/api/user_groups.js @@ -20,24 +20,23 @@ //@flow import { getJSON, post } from '../helpers/request'; -export function searchUsersGroups(query?: string, organization?: string) { +export function searchUsersGroups( + data: { f?: string, organization?: string, p?: number, ps?: number, q?: string } +) { const url = '/api/user_groups/search'; - const data: { q?: string, organization?: string } = {}; - if (query) { - data.q = query; - } - if (organization) { - data.organization = organization; - } return getJSON(url, data); } -export function addUserToGroup(groupId: string, login: string) { +export function addUserToGroup( + data: { id?: string, name?: string, login?: string, organization?: string } +) { const url = '/api/user_groups/add_user'; - return post(url, { id: groupId, login }); + return post(url, data); } -export function removeUserFromGroup(groupId: string, login: string) { +export function removeUserFromGroup( + data: { id?: string, name?: string, login?: string, organization?: string } +) { const url = '/api/user_groups/remove_user'; - return post(url, { id: groupId, login }); + return post(url, data); } diff --git a/server/sonar-web/src/main/js/apps/organizations/actions.js b/server/sonar-web/src/main/js/apps/organizations/actions.js index a67d6103e3e..db5727bdd36 100644 --- a/server/sonar-web/src/main/js/apps/organizations/actions.js +++ b/server/sonar-web/src/main/js/apps/organizations/actions.js @@ -59,11 +59,11 @@ export const fetchOrganization = (key: string): Function => ); }; -export const fetchOrganizationGroups = (key: string): Function => +export const fetchOrganizationGroups = (organization: string): Function => (dispatch: Function): Promise<*> => { - return searchUsersGroups('', key).then( + return searchUsersGroups({ organization }).then( response => { - dispatch(actions.receiveOrganizationGroups(key, response.groups)); + dispatch(actions.receiveOrganizationGroups(organization, response.groups)); }, onFail(dispatch) ); @@ -166,24 +166,26 @@ export const removeOrganizationMember = (key: string, member: Member) => }; export const updateOrganizationMemberGroups = ( + organization: Organization, member: Member, add: Array, remove: Array ) => (dispatch: Function) => { + dispatch( + receiveUser({ + ...member, + groupCount: (member.groupCount || 0) + add.length - remove.length + }) + ); const promises = [ - ...add.map(id => addUserToGroup(id, member.login)), - ...remove.map(id => removeUserFromGroup(id, member.login)) + ...add.map(name => + addUserToGroup({ name, login: member.login, organization: organization.key })), + ...remove.map(name => + removeUserFromGroup({ name, login: member.login, organization: organization.key })) ]; - return Promise.all(promises).then( - () => { - dispatch( - receiveUser({ - ...member, - groupCount: (member.groupCount || 0) + add.length - remove.length - }) - ); - }, - onFail(dispatch) - ); + return Promise.all(promises).catch(error => { + dispatch(receiveUser(member)); + onFail(dispatch)(error); + }); }; diff --git a/server/sonar-web/src/main/js/apps/organizations/components/OrganizationGroupCheckbox.js b/server/sonar-web/src/main/js/apps/organizations/components/OrganizationGroupCheckbox.js index ffe6fc463ce..3324cc4ec77 100644 --- a/server/sonar-web/src/main/js/apps/organizations/components/OrganizationGroupCheckbox.js +++ b/server/sonar-web/src/main/js/apps/organizations/components/OrganizationGroupCheckbox.js @@ -32,11 +32,11 @@ export default class OrganizationGroupCheckbox extends React.PureComponent { props: Props; onCheck = (checked: boolean) => { - this.props.onCheck(this.props.group.id, checked); + this.props.onCheck(this.props.group.name, checked); }; toggleCheck = () => { - this.props.onCheck(this.props.group.id, !this.props.checked); + this.props.onCheck(this.props.group.name, !this.props.checked); }; render() { 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 b4448548149..49eac0e3fa7 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 @@ -39,6 +39,7 @@ type Props = { addOrganizationMember: (organizationKey: string, member: Member) => void, removeOrganizationMember: (organizationKey: string, member: Member) => void, updateOrganizationMemberGroups: ( + organization: Organization, member: Member, add: Array, remove: Array @@ -71,6 +72,10 @@ export default class OrganizationMembers extends React.PureComponent { this.props.removeOrganizationMember(this.props.organization.key, member); }; + updateMemberGroups = (member: Member, add: Array, remove: Array) => { + this.props.updateOrganizationMemberGroups(this.props.organization, member, add, remove); + }; + render() { const { organization, status, members } = this.props; return ( @@ -89,7 +94,7 @@ export default class OrganizationMembers extends React.PureComponent { organizationGroups={this.props.organizationGroups} organization={organization} removeMember={this.removeMember} - updateMemberGroups={this.props.updateOrganizationMemberGroups} + updateMemberGroups={this.updateMemberGroups} /> {status.total != null && + removeMember={[Function]} + updateMemberGroups={[Function]} /> + removeMember={[Function]} + updateMemberGroups={[Function]} /> { this.setState({ loading: true }); getUserGroups(this.props.member.login, this.props.organization.key).then(response => { - this.setState({ loading: false, userGroups: keyBy(response.groups, 'id') }); + this.setState({ loading: false, userGroups: keyBy(response.groups, 'name') }); }); }; - isGroupSelected = (groupId: string) => { + isGroupSelected = (groupName: string) => { if (this.state.userGroups) { - const group = this.state.userGroups[groupId] || {}; + const group = this.state.userGroups[groupName] || {}; if (group.status) { return group.status === 'add'; } else { @@ -76,17 +76,17 @@ export default class ManageMemberGroupsForm extends React.PureComponent { return false; }; - onCheck = (groupId: string, checked: boolean) => { + onCheck = (groupName: string, checked: boolean) => { this.setState((prevState: State) => { const userGroups = prevState.userGroups || {}; - const group = userGroups[groupId] || {}; + const group = userGroups[groupName] || {}; let status = ''; if (group.selected && !checked) { status = 'remove'; } else if (!group.selected && checked) { status = 'add'; } - return { userGroups: { ...userGroups, [groupId]: { ...group, status } } }; + return { userGroups: { ...userGroups, [groupName]: { ...group, status } } }; }); }; @@ -125,7 +125,7 @@ export default class ManageMemberGroupsForm extends React.PureComponent { ))} diff --git a/server/sonar-web/src/main/js/apps/organizations/components/forms/__tests__/__snapshots__/AddMemberForm-test.js.snap b/server/sonar-web/src/main/js/apps/organizations/components/forms/__tests__/__snapshots__/AddMemberForm-test.js.snap index 8cae5645817..51167b86dcd 100644 --- a/server/sonar-web/src/main/js/apps/organizations/components/forms/__tests__/__snapshots__/AddMemberForm-test.js.snap +++ b/server/sonar-web/src/main/js/apps/organizations/components/forms/__tests__/__snapshots__/AddMemberForm-test.js.snap @@ -36,6 +36,7 @@ exports[`test should render and open the modal 2`] = ` users.search_description , + handleValueChange: (Option) => void, searchUsers: (string, number) => Promise<*>, - handleValueChange: (Option) => void + selectedUser?: Option }; type State = { - searchResult: Array