diff --git a/scm-ui/src/components/Checkbox.js b/scm-ui/src/components/Checkbox.js index 12d6f3f77f..346ff6bc2a 100644 --- a/scm-ui/src/components/Checkbox.js +++ b/scm-ui/src/components/Checkbox.js @@ -3,6 +3,7 @@ import React from "react"; type Props = { label: string, + checked: boolean, onChange: boolean => void }; class Checkbox extends React.Component { @@ -15,7 +16,11 @@ class Checkbox extends React.Component {
diff --git a/scm-ui/src/components/InputField.js b/scm-ui/src/components/InputField.js index 7ffe1f55bf..0bf44e1bdc 100644 --- a/scm-ui/src/components/InputField.js +++ b/scm-ui/src/components/InputField.js @@ -4,6 +4,7 @@ import React from "react"; type Props = { label?: string, placeholder?: string, + value?: string, type?: string, autofocus?: boolean, onChange: string => void @@ -36,7 +37,7 @@ class InputField extends React.Component { }; render() { - const { type, placeholder } = this.props; + const { type, placeholder, value } = this.props; return (
@@ -49,6 +50,7 @@ class InputField extends React.Component { className="input" type={type} placeholder={placeholder} + value={value} onChange={this.handleInput} />
diff --git a/scm-ui/src/users/containers/UserForm.js b/scm-ui/src/users/containers/UserForm.js index 6c01fb7a18..8c002b1da9 100644 --- a/scm-ui/src/users/containers/UserForm.js +++ b/scm-ui/src/users/containers/UserForm.js @@ -11,46 +11,63 @@ type Props = { }; class UserForm extends React.Component { + constructor(props: Props) { + super(props); + this.state = { + name: "", + displayName: "", + mail: "", + password: "", + admin: false, + active: false + }; + } + submit = (event: Event) => { event.preventDefault(); this.props.submitForm(this.state); }; + componentWillReceiveProps() { + this.setState(this.props.user); + } + render() { - const { submitForm, user } = this.props; + const { submitForm } = this.props; + const user = this.state; return (
diff --git a/scm-ui/src/users/containers/UserRow.js b/scm-ui/src/users/containers/UserRow.js index 40b0628031..c55af67d58 100644 --- a/scm-ui/src/users/containers/UserRow.js +++ b/scm-ui/src/users/containers/UserRow.js @@ -1,16 +1,18 @@ // @flow import React from "react"; import DeleteUserButton from "./DeleteUserButton"; +import EditUserButton from "./EditUserButton"; import type { User } from "../types/User"; type Props = { entry: { loading: boolean, error: Error, user: User }, - deleteUser: string => void + deleteUser: string => void, + editUser: User => void }; export default class UserRow extends React.Component { render() { - const { deleteUser } = this.props; + const { deleteUser, editUser } = this.props; const user = this.props.entry.entry; return ( @@ -23,6 +25,9 @@ export default class UserRow extends React.Component { + + + ); } diff --git a/scm-ui/src/users/containers/UserTable.js b/scm-ui/src/users/containers/UserTable.js index 9379945342..23be3b9845 100644 --- a/scm-ui/src/users/containers/UserTable.js +++ b/scm-ui/src/users/containers/UserTable.js @@ -1,16 +1,18 @@ // @flow import React from "react"; import UserRow from "./UserRow"; +import { editUser } from "../modules/users"; import type { User } from "../types/User"; type Props = { entries: [{ loading: boolean, error: Error, user: User }], - deleteUser: string => void + deleteUser: string => void, + editUser: User => void }; class UserTable extends React.Component { render() { - const { deleteUser } = this.props; + const { deleteUser, editUser } = this.props; const entries = this.props.entries; return ( @@ -25,7 +27,12 @@ class UserTable extends React.Component { {entries.map((entry, index) => { return ( - + ); })} diff --git a/scm-ui/src/users/containers/Users.js b/scm-ui/src/users/containers/Users.js index 04b983d750..9a91b90cf3 100644 --- a/scm-ui/src/users/containers/Users.js +++ b/scm-ui/src/users/containers/Users.js @@ -5,6 +5,7 @@ import { connect } from "react-redux"; import { fetchUsers, addUser, + updateUser, editUser, deleteUser, getUsersFromState @@ -26,10 +27,12 @@ type Props = { fetchUsers: () => void, deleteUser: string => void, addUser: User => void, - editUser: User => void + updateUser: User => void, + editUser: User => void, + userToEdit: User }; -class Users extends React.Component { +class Users extends React.Component { componentDidMount() { this.props.fetchUsers(); } @@ -38,29 +41,43 @@ class Users extends React.Component { this.props.addUser(user); }; - editUser = (user: User) => { - this.props.editUser(user); + updateUser = (user: User) => { + this.props.updateUser(user); + }; + + componentDidUpdate(prevProps: Props) { + if (prevProps.userToEdit !== this.props.userToEdit) { + this.setState(this.props.userToEdit); + } + } + + submitUser = (user: User) => { + if (user._links && user._links.update) { + this.updateUser(user); + } else { + this.addUser(user); + } }; render() { - const { userEntries, deleteUser } = this.props; - const testUser: User = { - name: "user", - displayName: "user_display", - password: "pw", - mail: "mail@mail.de", - active: true, - admin: true - }; + const { userEntries, deleteUser, editUser } = this.props; if (userEntries) { return (

SCM

Users

- - {/* */} - {}} user={testUser} /> + { + this.props.editUser(user); + }} + /> + this.submitUser(user)} + user={this.props.userToEdit} + />
); @@ -72,11 +89,13 @@ class Users extends React.Component { const mapStateToProps = state => { const userEntries = getUsersFromState(state); + var userToEdit = state.users.editUser; if (!userEntries) { - return {}; + return { userToEdit }; } return { - userEntries + userEntries, + userToEdit }; }; @@ -88,11 +107,14 @@ const mapDispatchToProps = dispatch => { addUser: (user: User) => { dispatch(addUser(user)); }, - editUser: (user: User) => { - dispatch(editUser(user)); + updateUser: (user: User) => { + dispatch(updateUser(user)); }, deleteUser: (link: string) => { dispatch(deleteUser(link)); + }, + editUser: (user: User) => { + dispatch(editUser(user)); } }; }; diff --git a/scm-ui/src/users/modules/users.js b/scm-ui/src/users/modules/users.js index 2e1b3686f4..e4227176ac 100644 --- a/scm-ui/src/users/modules/users.js +++ b/scm-ui/src/users/modules/users.js @@ -2,6 +2,7 @@ import { apiClient, NOT_FOUND_ERROR } from "../../apiclient"; import type { User } from "../types/User"; import { ThunkDispatch } from "redux-thunk"; +import { Dispatch } from "redux"; export const FETCH_USERS = "scm/users/FETCH"; export const FETCH_USERS_SUCCESS = "scm/users/FETCH_SUCCESS"; @@ -13,8 +14,10 @@ export const ADD_USER_SUCCESS = "scm/users/ADD_SUCCESS"; export const ADD_USER_FAILURE = "scm/users/ADD_FAILURE"; export const EDIT_USER = "scm/users/EDIT"; -export const EDIT_USER_SUCCESS = "scm/users/EDIT_SUCCESS"; -export const EDIT_USER_FAILURE = "scm/users/EDIT_FAILURE"; + +export const UPDATE_USER = "scm/users/UPDATE"; +export const UPDATE_USER_SUCCESS = "scm/users/UPDATE_SUCCESS"; +export const UPDATE_USER_FAILURE = "scm/users/UPDATE_FAILURE"; export const DELETE_USER = "scm/users/DELETE"; export const DELETE_USER_SUCCESS = "scm/users/DELETE_SUCCESS"; @@ -85,7 +88,7 @@ function requestAddUser(user: User) { } export function addUser(user: User) { - return function(dispatch: ThunkDispatch) { + return function(dispatch: Dispatch) { dispatch(requestAddUser(user)); return apiClient .postWithContentType(USERS_URL, user, CONTENT_TYPE_USER) @@ -111,9 +114,36 @@ function addUserFailure(user: User, err: Error) { }; } -function requestAddUser(user: User) { +function requestUpdateUser(user: User) { return { - type: ADD_USER, + type: UPDATE_USER, + user + }; +} + +export function updateUser(user: User) { + return function(dispatch: Dispatch) { + dispatch(requestUpdateUser(user)); + return apiClient + .putWithContentType(user._links.update.href, user, CONTENT_TYPE_USER) + .then(() => { + dispatch(updateUserSuccess()); + dispatch(fetchUsers()); + }) + .catch(err => dispatch(updateUserFailure(user, err))); + }; +} + +function updateUserSuccess() { + return { + type: UPDATE_USER_SUCCESS + }; +} + +function updateUserFailure(user: User, error: Error) { + return { + type: UPDATE_USER_FAILURE, + payload: error, user }; } @@ -131,20 +161,6 @@ export function editUser(user: User) { }; } -function editUserSuccess() { - return { - type: ADD_USER_SUCCESS - }; -} - -function addUserFailure(user: User, err: Error) { - return { - type: ADD_USER_FAILURE, - payload: err, - user - }; -} - function requestDeleteUser(url: string) { return { type: DELETE_USER, @@ -215,6 +231,13 @@ function extractUsersByNames( return usersByNames; } +function editUser(user: User) { + return { + type: EDIT_USER, + user + }; +} + export default function reducer(state: any = {}, action: any = {}) { switch (action.type) { case FETCH_USERS: @@ -253,7 +276,11 @@ export default function reducer(state: any = {}, action: any = {}) { error: action.payload, loading: false }; - + case EDIT_USER: + return { + ...state, + editUser: action.user + }; default: return state; }