diff --git a/scm-ui/public/locales/en/groups.json b/scm-ui/public/locales/en/groups.json index e0adfcf0c7..6aad6fd8aa 100644 --- a/scm-ui/public/locales/en/groups.json +++ b/scm-ui/public/locales/en/groups.json @@ -29,15 +29,15 @@ "edit-group-button": { "label": "Edit" }, - "add-user-button": { - "label": "Add user" + "add-member-button": { + "label": "Add member" }, - "remove-user-button": { - "label": "Remove user" + "remove-member-button": { + "label": "Remove member" }, - "add-user-textfield": { - "label": "Add user", - "error": "Username invalid" + "add-member-textfield": { + "label": "Add member", + "error": "Invalid member name" }, "group-form": { "submit": "Submit", diff --git a/scm-ui/src/groups/components/AddUserField.js b/scm-ui/src/groups/components/AddMemberField.js similarity index 51% rename from scm-ui/src/groups/components/AddUserField.js rename to scm-ui/src/groups/components/AddMemberField.js index 4c749e7ca5..2a5b368215 100644 --- a/scm-ui/src/groups/components/AddUserField.js +++ b/scm-ui/src/groups/components/AddMemberField.js @@ -8,19 +8,19 @@ import { isMemberNameValid } from "./groupValidation" type Props = { t: string => string, - addUser: string => void + addMember: string => void }; type State = { - userToAdd: string, + memberToAdd: string, validationError: boolean }; -class AddUserField extends React.Component { +class AddMemberField extends React.Component { constructor(props) { super(props); this.state = { - userToAdd: "", + memberToAdd: "", validationError: false }; } @@ -30,16 +30,15 @@ class AddUserField extends React.Component { return (
@@ -53,13 +52,14 @@ class AddUserField extends React.Component { }; appendMember = () => { - this.props.addUser(this.state.userToAdd); - this.setState({ ...this.state, userToAdd: "" }); - } + this.props.addMember(this.state.memberToAdd); + this.setState({ ...this.state, memberToAdd: "" }); + }; - handleAddUserChange = (username: string) => { - this.setState({ ...this.state, userToAdd: username, validationError: !isMemberNameValid(username)}); + + handleAddMemberChange = (membername: string) => { + this.setState({ ...this.state, memberToAdd: membername, validationError: !isMemberNameValid(membername) }); }; } -export default translate("groups")(AddUserField); +export default translate("groups")(AddMemberField); diff --git a/scm-ui/src/groups/components/GroupForm.js b/scm-ui/src/groups/components/GroupForm.js index 94363ba86f..27f6d8c605 100644 --- a/scm-ui/src/groups/components/GroupForm.js +++ b/scm-ui/src/groups/components/GroupForm.js @@ -6,8 +6,8 @@ import { SubmitButton } from "../../components/buttons"; import { translate } from "react-i18next"; import type { Group } from "../types/Group"; import * as validator from "./groupValidation"; -import AddUserField from "./AddUserField"; -import UserNameTable from "./UserNameTable"; +import AddMemberField from "./AddMemberField"; +import MemberNameTable from "./MemberNameTable"; type Props = { t: string => string, @@ -95,11 +95,11 @@ class GroupForm extends React.Component { value={group.description} validationError={false} /> - - + { ); } - userListChanged = usernames => { + memberListChanged = membernames => { this.setState({ ...this.state, group: { ...this.state.group, - members: usernames + members: membernames } }); - } + }; - - addUser = (username: string) => { - if (this.isMember(username)) { + addMember = (membername: string) => { + if (this.isMember(membername)) { return; } @@ -129,13 +128,13 @@ class GroupForm extends React.Component { ...this.state, group: { ...this.state.group, - members: [...this.state.group.members, username] + members: [...this.state.group.members, membername] } }); }; - isMember = (username: string) => { - return this.state.group.members.includes(username); + isMember = (membername: string) => { + return this.state.group.members.includes(membername); }; handleGroupNameChange = (name: string) => { diff --git a/scm-ui/src/groups/components/MemberNameTable.js b/scm-ui/src/groups/components/MemberNameTable.js new file mode 100644 index 0000000000..c85e88994c --- /dev/null +++ b/scm-ui/src/groups/components/MemberNameTable.js @@ -0,0 +1,47 @@ +//@flow +import React from "react"; +import { translate } from "react-i18next"; +import RemoveMemberButton from "./buttons/RemoveMemberButton"; + +type Props = { + members: string[], + t: string => string, + memberListChanged: (string[]) => void +}; + +type State = {}; + +class MemberNameTable extends React.Component { + render() { + const { t } = this.props; + return ( +
+ + + + {this.props.members.map((member, index) => { + return ( + + + + + ); + })} + +
{member} + +
+
+ ); + } + + removeMember = (membername: string) => { + const newMembers = this.props.members.filter(name => name !== membername); + this.props.memberListChanged(newMembers); + }; +} + +export default translate("groups")(MemberNameTable); diff --git a/scm-ui/src/groups/components/UserNameTable.js b/scm-ui/src/groups/components/UserNameTable.js deleted file mode 100644 index e79bd523d4..0000000000 --- a/scm-ui/src/groups/components/UserNameTable.js +++ /dev/null @@ -1,46 +0,0 @@ -//@flow -import React from "react"; -import { translate } from "react-i18next" -import RemoveUserButton from "./buttons/RemoveUserButton"; - -type Props = { - users: string[]; - t: string => string, - userListChanged: (string[]) => void -}; - -type State = { -}; - - -class UserNameTable extends React.Component { - render() { - const { t } = this.props; - return ( -
- - - - {this.props.users.map((user, index) => { - return ( - - - - - ); - })} - -
{user} - -
-
- ); - } - - removeUser = (username: string) => { - const newUsers = this.props.users.filter(name => name !== username); - this.props.userListChanged(newUsers); - } -} - -export default translate("groups")(UserNameTable); diff --git a/scm-ui/src/groups/components/buttons/RemoveUserButton.js b/scm-ui/src/groups/components/buttons/RemoveMemberButton.js similarity index 59% rename from scm-ui/src/groups/components/buttons/RemoveUserButton.js rename to scm-ui/src/groups/components/buttons/RemoveMemberButton.js index 4474b325f7..40c7b39cc0 100644 --- a/scm-ui/src/groups/components/buttons/RemoveUserButton.js +++ b/scm-ui/src/groups/components/buttons/RemoveMemberButton.js @@ -6,24 +6,24 @@ import classNames from "classnames"; type Props = { t: string => string, - username: string, - removeUser: string => void + membername: string, + removeMember: string => void }; type State = {}; -class RemoveUserButton extends React.Component { +class RemoveMemberButton extends React.Component { render() { - const { t , username, removeUser} = this.props; + const { t , membername, removeMember} = this.props; return (
{ event.preventDefault(); - removeUser(username); + removeMember(membername); }} />
@@ -31,4 +31,4 @@ class RemoveUserButton extends React.Component { } } -export default translate("groups")(RemoveUserButton); +export default translate("groups")(RemoveMemberButton); diff --git a/scm-ui/src/groups/components/table/GroupMember.js b/scm-ui/src/groups/components/table/GroupMember.js index ee5722c75a..3777b27660 100644 --- a/scm-ui/src/groups/components/table/GroupMember.js +++ b/scm-ui/src/groups/components/table/GroupMember.js @@ -1,10 +1,10 @@ // @flow import React from "react"; import { Link } from "react-router-dom"; -import type { User } from "../../../users/types/User"; +import type { Member } from "../../types/Group"; type Props = { - member: User + member: Member }; export default class GroupMember extends React.Component { @@ -12,7 +12,7 @@ export default class GroupMember extends React.Component { return {label}; } - showName(to: any, member: User) { + showName(to: any, member: Member) { if (member._links.self) { return this.renderLink(to, member.name); } else { diff --git a/scm-ui/src/groups/modules/groups.js b/scm-ui/src/groups/modules/groups.js index b9fc3bef80..39526c19a0 100644 --- a/scm-ui/src/groups/modules/groups.js +++ b/scm-ui/src/groups/modules/groups.js @@ -1,3 +1,4 @@ +// @flow import { apiClient } from "../../apiclient"; import { isPending } from "../../modules/pending"; import { getFailure } from "../../modules/failure"; @@ -5,7 +6,7 @@ import * as types from "../../modules/types"; import { combineReducers, Dispatch } from "redux"; import type { Action } from "../../types/Action"; import type { PagedCollection } from "../../types/Collection"; -import type { Groups } from "../types/Groups"; +import type { Group } from "../types/Group"; export const FETCH_GROUPS = "scm/groups/FETCH_GROUPS"; export const FETCH_GROUPS_PENDING = `${FETCH_GROUPS}_${types.PENDING_SUFFIX}`; @@ -139,10 +140,11 @@ export function createGroup(group: Group, callback?: () => void) { return apiClient .postWithContentType(GROUPS_URL, group, CONTENT_TYPE_GROUP) .then(() => { - dispatch(createGroupSuccess()) - if (callback) { - callback(); - }}) + dispatch(createGroupSuccess()); + if (callback) { + callback(); + } + }) .catch(error => { dispatch( createGroupFailure( @@ -175,24 +177,29 @@ export function createGroupFailure(error: Error) { export function createGroupReset() { return { type: CREATE_GROUP_RESET - } + }; } -// modify group +// modify group export function modifyGroup(group: Group, callback?: () => void) { return function(dispatch: Dispatch) { dispatch(modifyGroupPending(group)); return apiClient - .putWithContentType(group._links.update.href, group, CONTENT_TYPE_GROUP) - .then(() => { - dispatch(modifyGroupSuccess(group)) - if (callback) { - callback() - } - }) - .catch(cause => { - dispatch(modifyGroupFailure(group, new Error(`could not modify group ${group.name}: ${cause.message}`))) - }) + .putWithContentType(group._links.update.href, group, CONTENT_TYPE_GROUP) + .then(() => { + dispatch(modifyGroupSuccess(group)); + if (callback) { + callback(); + } + }) + .catch(cause => { + dispatch( + modifyGroupFailure( + group, + new Error(`could not modify group ${group.name}: ${cause.message}`) + ) + ); + }); }; } @@ -201,7 +208,7 @@ export function modifyGroupPending(group: Group): Action { type: MODIFY_GROUP_PENDING, payload: group, itemId: group.name - } + }; } export function modifyGroupSuccess(group: Group): Action { @@ -209,7 +216,7 @@ export function modifyGroupSuccess(group: Group): Action { type: MODIFY_GROUP_SUCCESS, payload: group, itemId: group.name - } + }; } export function modifyGroupFailure(group: Group, error: Error): Action { @@ -220,7 +227,7 @@ export function modifyGroupFailure(group: Group, error: Error): Action { group }, itemId: group.name - } + }; } //delete group @@ -274,7 +281,7 @@ export function deleteGroupFailure(group: Group, error: Error): Action { //reducer function extractGroupsByNames( - groups: Groups[], + groups: Group[], groupNames: string[], oldGroupsByNames: Object ) { @@ -332,14 +339,14 @@ function listReducer(state: any = {}, action: any = {}) { }; // Delete single group actions case DELETE_GROUP_SUCCESS: - const newGroupEntries = deleteGroupInEntries( - state.entries, - action.payload.name - ); - return { - ...state, - entries: newGroupEntries - }; + const newGroupEntries = deleteGroupInEntries( + state.entries, + action.payload.name + ); + return { + ...state, + entries: newGroupEntries + }; default: return state; } @@ -357,7 +364,7 @@ function byNamesReducer(state: any = {}, action: any = {}) { }; case FETCH_GROUP_SUCCESS: return reducerByName(state, action.payload.name, action.payload); - case MODIFY_GROUP_SUCCESS: + case MODIFY_GROUP_SUCCESS: return reducerByName(state, action.payload.name, action.payload); case DELETE_GROUP_SUCCESS: const newGroupByNames = deleteGroupInGroupsByNames( @@ -436,11 +443,11 @@ export function getCreateGroupFailure(state: Object) { } export function isModifyGroupPending(state: Object, name: string) { - return(isPending(state, MODIFY_GROUP, name)) + return isPending(state, MODIFY_GROUP, name); } export function getModifyGroupFailure(state: Object, name: string) { - return(getFailure(state, MODIFY_GROUP, name)) + return getFailure(state, MODIFY_GROUP, name); } export function getGroupByName(state: Object, name: string) { diff --git a/scm-ui/src/groups/types/Group.js b/scm-ui/src/groups/types/Group.js index 92ed18b822..420d724784 100644 --- a/scm-ui/src/groups/types/Group.js +++ b/scm-ui/src/groups/types/Group.js @@ -1,14 +1,18 @@ //@flow +import type { Collection } from "../../types/Collection"; import type { Links } from "../../types/hal"; -import type { User } from "../../users/types/User"; -export type Group = { +export type Member = { + name: string, + _links: Links +}; + +export type Group = Collection & { name: string, description: string, type: string, members: string[], - _links: Links, _embedded: { - members: User[] + members: Member[] } };