diff --git a/client/src/javascript/components/modals/settings-modal/AuthTab.tsx b/client/src/javascript/components/modals/settings-modal/AuthTab.tsx index 5e0aeee2..6f87639b 100644 --- a/client/src/javascript/components/modals/settings-modal/AuthTab.tsx +++ b/client/src/javascript/components/modals/settings-modal/AuthTab.tsx @@ -1,8 +1,8 @@ import classnames from 'classnames'; import {CSSTransition, TransitionGroup} from 'react-transition-group'; -import {FormattedMessage, injectIntl, WrappedComponentProps} from 'react-intl'; +import {FC, useEffect, useRef, useState} from 'react'; +import {FormattedMessage, useIntl} from 'react-intl'; import {observer} from 'mobx-react'; -import * as React from 'react'; import {AccessLevel} from '@shared/schema/constants/Auth'; import type {Credentials} from '@shared/schema/Auth'; @@ -22,229 +22,182 @@ interface AuthTabFormData { isAdmin: boolean; } -interface AuthTabStates { - addUserError: string | null; - hasFetchedUserList: boolean; - isAddingUser: boolean; -} +const AuthTab: FC = observer(() => { + const formRef = useRef
(null); + const settingsFormRef = useRef(null); + const [error, setError] = useState(null); + const [isUserListFetched, setIsUserListFetched] = useState(false); + const [isSubmitting, setIsSubmitting] = useState(false); + const intl = useIntl(); -@observer -class AuthTab extends React.Component { - formData?: Partial; - - formRef?: Form | null = null; - - settingsFormRef: React.RefObject = React.createRef(); - - constructor(props: WrappedComponentProps) { - super(props); - - this.state = { - addUserError: null, - hasFetchedUserList: false, - isAddingUser: false, - }; - } - - componentDidMount() { - if (!AuthStore.currentUser.isAdmin) { - return; - } - - AuthActions.fetchUsers().then(() => { - this.setState({hasFetchedUserList: true}); - }); - } - - handleFormChange = ({formData}: {formData: Record}) => { - this.formData = formData as Partial; - }; - - handleFormSubmit = () => { - if (this.formData == null || this.settingsFormRef.current == null) { - return; - } - - if (this.formData.username == null || this.formData.username === '') { - this.setState({ - addUserError: this.props.intl.formatMessage({ - id: 'auth.error.username.empty', - }), + useEffect(() => { + if (AuthStore.currentUser.isAdmin) { + AuthActions.fetchUsers().then(() => { + setIsUserListFetched(true); }); - } else if (this.formData.password == null || this.formData.password === '') { - this.setState({ - addUserError: this.props.intl.formatMessage({ - id: 'auth.error.password.empty', - }), - }); - } else { - this.setState({isAddingUser: true}); - - const connectionSettings = this.settingsFormRef.current.getConnectionSettings(); - if (connectionSettings == null) { - this.setState({ - addUserError: this.props.intl.formatMessage({ - id: 'connection.settings.error.empty', - }), - isAddingUser: false, - }); - return; - } - - AuthActions.createUser({ - username: this.formData.username, - password: this.formData.password, - client: connectionSettings, - level: this.formData.isAdmin === true ? AccessLevel.ADMINISTRATOR : AccessLevel.USER, - }) - .then(AuthActions.fetchUsers, (error) => { - this.setState({ - addUserError: error.response.data.message, - isAddingUser: false, - }); - }) - .then(() => { - if (this.formRef != null) { - this.formRef.resetForm(); - } - this.setState({addUserError: null, isAddingUser: false}); - }); - } - }; - - render() { - const {addUserError, hasFetchedUserList} = this.state; - - if (!AuthStore.currentUser.isAdmin) { - return ( - - - - - - - - - - - ); - } - - const isLoading = !hasFetchedUserList && AuthStore.users.length === 0; - const interactiveListClasses = classnames('interactive-list', { - 'interactive-list--loading': isLoading, - }); - let errorElement = null; - let loadingIndicator = null; - - if (addUserError) { - errorElement = ( - - {addUserError} - - ); - } - - if (isLoading) { - loadingIndicator = ( - -
- -
-
- ); } + }, []); + if (!AuthStore.currentUser.isAdmin) { return ( -
{ - this.formRef = ref; - }}> + - -
    - {loadingIndicator} - {AuthStore.users - .slice() - .sort((a: Credentials, b: Credentials) => a.username.localeCompare(b.username)) - .map((user: Credentials) => { - const isCurrentUser = user.username === AuthStore.currentUser.username; - let badge = null; - let removeIcon = null; - - if (!isCurrentUser) { - removeIcon = ( - AuthActions.deleteUser(user.username).then(AuthActions.fetchUsers)}> - - - ); - } else { - badge = ( - - - - ); - } - - const classes = classnames('interactive-list__item', { - 'interactive-list__item--disabled': isCurrentUser, - }); - - return ( -
  • - -
    {user.username}
    - {badge} -
    - {removeIcon} -
  • - ); - })} -
-
-
- - - - {errorElement} - - } - placeholder={this.props.intl.formatMessage({ - id: 'auth.username', - })} - autoComplete="username" - /> - } - placeholder={this.props.intl.formatMessage({ - id: 'auth.password', - })} - autoComplete="new-password" - /> - - - - - -

- - + + +

); } -} -export default injectIntl(AuthTab); + const isLoading = !isUserListFetched && AuthStore.users.length === 0; + const interactiveListClasses = classnames('interactive-list', { + 'interactive-list--loading': isLoading, + }); + + return ( +
{ + if (formRef.current == null || settingsFormRef.current == null) { + return; + } + + const formData = formRef.current.getFormData() as Partial; + + if (formData.username == null || formData.username === '') { + setError('auth.error.username.empty'); + } else if (formData.password == null || formData.password === '') { + setError('auth.error.password.empty'); + } else { + setIsSubmitting(true); + + const connectionSettings = settingsFormRef.current.getConnectionSettings(); + if (connectionSettings == null) { + setError('connection.settings.error.empty'); + setIsSubmitting(false); + return; + } + + AuthActions.createUser({ + username: formData.username, + password: formData.password, + client: connectionSettings, + level: formData.isAdmin === true ? AccessLevel.ADMINISTRATOR : AccessLevel.USER, + }) + .then( + () => { + if (formRef.current != null) { + formRef.current.resetForm(); + } + setError(null); + setIsSubmitting(false); + }, + () => { + setError('general.error.unknown'); + setIsSubmitting(false); + }, + ) + .then(AuthActions.fetchUsers); + } + }} + ref={formRef}> + + + + + +
    + + {isLoading && ( + +
    + +
    +
    + )} +
    + {AuthStore.users + .slice() + .sort((a: Credentials, b: Credentials) => a.username.localeCompare(b.username)) + .map((user: Credentials) => { + const isCurrentUser = user.username === AuthStore.currentUser.username; + let badge = null; + let removeIcon = null; + + if (!isCurrentUser) { + removeIcon = ( + AuthActions.deleteUser(user.username).then(AuthActions.fetchUsers)}> + + + ); + } else { + badge = ( + + + + ); + } + + const classes = classnames('interactive-list__item', { + 'interactive-list__item--disabled': isCurrentUser, + }); + + return ( +
  • + +
    {user.username}
    + {badge} +
    + {removeIcon} +
  • + ); + })} +
+
+
+ + + + {error && ( + + {intl.formatMessage({id: error})} + + )} + + } + placeholder={intl.formatMessage({ + id: 'auth.username', + })} + autoComplete="username" + /> + } + placeholder={intl.formatMessage({ + id: 'auth.password', + })} + autoComplete="new-password" + /> + + + + + +

+ + + +

+ ); +}); + +export default AuthTab;