From a3c00b9e12bb5d495bba33346bac3844a00195ef Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Mon, 6 Aug 2018 13:55:54 +0200 Subject: [PATCH 1/2] improve typing and fixed import --- scm-ui/src/groups/components/GroupForm.js | 5 +- scm-ui/src/groups/modules/groups.js | 71 +++++++++++++---------- scm-ui/src/groups/types/Group.js | 12 ++-- 3 files changed, 49 insertions(+), 39 deletions(-) diff --git a/scm-ui/src/groups/components/GroupForm.js b/scm-ui/src/groups/components/GroupForm.js index f822a53764..1c4c1848e7 100644 --- a/scm-ui/src/groups/components/GroupForm.js +++ b/scm-ui/src/groups/components/GroupForm.js @@ -2,7 +2,7 @@ import React from "react"; import InputField from "../../components/forms/InputField"; -import { SubmitButton, Button } from "../../components/buttons"; +import { SubmitButton } from "../../components/buttons"; import { translate } from "react-i18next"; import type { Group } from "../types/Group"; import * as validator from "./groupValidation"; @@ -117,8 +117,7 @@ class GroupForm extends React.Component { members: usernames } }); - } - + }; addUser = (username: string) => { if (this.isMember(username)) { 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[] } }; From 762044868c42ab0f45ab1565c5b2268f661ccb07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maren=20S=C3=BCwer?= Date: Tue, 7 Aug 2018 15:51:02 +0200 Subject: [PATCH 2/2] refactoring: change user to member since members do not have to be users --- scm-ui/public/locales/en/groups.json | 14 ++--- .../src/groups/components/AddMemberField.js | 54 +++++++++++++++++++ scm-ui/src/groups/components/AddUserField.js | 54 ------------------- scm-ui/src/groups/components/GroupForm.js | 26 ++++----- .../src/groups/components/MemberNameTable.js | 47 ++++++++++++++++ scm-ui/src/groups/components/UserNameTable.js | 47 ---------------- ...oveUserButton.js => RemoveMemberButton.js} | 14 ++--- .../groups/components/table/GroupMember.js | 20 +++---- 8 files changed, 136 insertions(+), 140 deletions(-) create mode 100644 scm-ui/src/groups/components/AddMemberField.js delete mode 100644 scm-ui/src/groups/components/AddUserField.js create mode 100644 scm-ui/src/groups/components/MemberNameTable.js delete mode 100644 scm-ui/src/groups/components/UserNameTable.js rename scm-ui/src/groups/components/buttons/{RemoveUserButton.js => RemoveMemberButton.js} (59%) diff --git a/scm-ui/public/locales/en/groups.json b/scm-ui/public/locales/en/groups.json index 5de5c15974..47d68d209a 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": "Error adding user" + "add-member-textfield": { + "label": "Add member", + "error": "Error adding member" }, "group-form": { "submit": "Submit", diff --git a/scm-ui/src/groups/components/AddMemberField.js b/scm-ui/src/groups/components/AddMemberField.js new file mode 100644 index 0000000000..e798c03099 --- /dev/null +++ b/scm-ui/src/groups/components/AddMemberField.js @@ -0,0 +1,54 @@ +//@flow +import React from "react"; + +import { translate } from "react-i18next"; +import AddButton from "../../components/buttons/AddButton"; +import InputField from "../../components/forms/InputField"; + +type Props = { + t: string => string, + addMember: string => void +}; + +type State = { + memberToAdd: string +}; + +class AddMemberField extends React.Component { + constructor(props) { + super(props); + this.state = { + memberToAdd: "" + }; + } + render() { + const { t } = this.props; + return ( +
+ + +
+ ); + } + + addButtonClicked = (event: Event) => { + event.preventDefault(); + this.props.addMember(this.state.memberToAdd); + this.setState({ ...this.state, memberToAdd: "" }); + }; + + handleAddMemberChange = (membername: string) => { + this.setState({ ...this.state, memberToAdd: membername }); + }; +} + +export default translate("groups")(AddMemberField); diff --git a/scm-ui/src/groups/components/AddUserField.js b/scm-ui/src/groups/components/AddUserField.js deleted file mode 100644 index 6fcb5770a0..0000000000 --- a/scm-ui/src/groups/components/AddUserField.js +++ /dev/null @@ -1,54 +0,0 @@ -//@flow -import React from "react"; - -import { translate } from "react-i18next"; -import AddButton from "../../components/buttons/AddButton"; -import InputField from "../../components/forms/InputField"; - -type Props = { - t: string => string, - addUser: string => void -}; - -type State = { - userToAdd: string -}; - -class AddUserField extends React.Component { - constructor(props) { - super(props); - this.state = { - userToAdd: "" - }; - } - render() { - const { t } = this.props; - return ( -
- - -
- ); - } - - addButtonClicked = (event: Event) => { - event.preventDefault(); - this.props.addUser(this.state.userToAdd); - this.setState({ ...this.state, userToAdd: "" }); - }; - - handleAddUserChange = (username: string) => { - this.setState({ ...this.state, userToAdd: username }); - }; -} - -export default translate("groups")(AddUserField); diff --git a/scm-ui/src/groups/components/GroupForm.js b/scm-ui/src/groups/components/GroupForm.js index 1c4c1848e7..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; } @@ -128,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 d7049aee31..0000000000 --- a/scm-ui/src/groups/components/UserNameTable.js +++ /dev/null @@ -1,47 +0,0 @@ -//@flow -import React from "react"; -import Button from "../../components/buttons/Button" -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 d372a5075f..cef7766a5d 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,12 +12,11 @@ export default class GroupMember extends React.Component { return {label}; } - showName(to: any, member:User) { - if(member._links.self){ - return this.renderLink(to, member.name); - } - else { - return member.name + showName(to: any, member: Member) { + if (member._links.self) { + return this.renderLink(to, member.name); + } else { + return member.name; } } @@ -26,11 +25,8 @@ export default class GroupMember extends React.Component { const to = `/user/${member.name}`; return ( - - {this.showName(to, member)} - + {this.showName(to, member)} - ); } }