diff --git a/client/modules/User/components/APIKeyForm.jsx b/client/modules/User/components/APIKeyForm.jsx index 17139a8953..eff0ae2d7b 100644 --- a/client/modules/User/components/APIKeyForm.jsx +++ b/client/modules/User/components/APIKeyForm.jsx @@ -1,135 +1,113 @@ import PropTypes from 'prop-types'; -import React from 'react'; +import React, { useState } from 'react'; +import { useTranslation } from 'react-i18next'; +import { useDispatch, useSelector } from 'react-redux'; import Button from '../../../common/Button'; import { PlusIcon } from '../../../common/icons'; import CopyableInput from '../../IDE/components/CopyableInput'; +import { createApiKey, removeApiKey } from '../actions'; import APIKeyList from './APIKeyList'; export const APIKeyPropType = PropTypes.shape({ - id: PropTypes.objectOf(PropTypes.shape()).isRequired, - token: PropTypes.objectOf(PropTypes.shape()), + id: PropTypes.string.isRequired, + token: PropTypes.string, label: PropTypes.string.isRequired, createdAt: PropTypes.string.isRequired, lastUsedAt: PropTypes.string }); -class APIKeyForm extends React.Component { - constructor(props) { - super(props); - this.state = { keyLabel: '' }; +const APIKeyForm = () => { + const { t } = useTranslation(); + const apiKeys = useSelector((state) => state.user.apiKeys); + const dispatch = useDispatch(); - this.addKey = this.addKey.bind(this); - this.removeKey = this.removeKey.bind(this); - this.renderApiKeys = this.renderApiKeys.bind(this); - } + const [keyLabel, setKeyLabel] = useState(''); - addKey(event) { + const addKey = (event) => { event.preventDefault(); - const { keyLabel } = this.state; + dispatch(createApiKey(keyLabel)); + setKeyLabel(''); + }; - this.setState({ - keyLabel: '' - }); - - this.props.createApiKey(keyLabel); - - return false; - } - - removeKey(key) { - const message = this.props.t('APIKeyForm.ConfirmDelete', { + const removeKey = (key) => { + const message = t('APIKeyForm.ConfirmDelete', { key_label: key.label }); if (window.confirm(message)) { - this.props.removeApiKey(key.id); + dispatch(removeApiKey(key.id)); } - } + }; - renderApiKeys() { - const hasApiKeys = this.props.apiKeys && this.props.apiKeys.length > 0; + const renderApiKeys = () => { + const hasApiKeys = apiKeys && apiKeys.length > 0; if (hasApiKeys) { - return ( - - ); + return ; } - return

{this.props.t('APIKeyForm.NoTokens')}

; - } - - render() { - const keyWithToken = this.props.apiKeys.find((k) => !!k.token); - - return ( -
-

- {this.props.t('APIKeyForm.Summary')} -

- -
-

- {this.props.t('APIKeyForm.CreateToken')} -

-
- - { - this.setState({ keyLabel: event.target.value }); - }} - placeholder={this.props.t('APIKeyForm.TokenPlaceholder')} - type="text" - value={this.state.keyLabel} + return

{t('APIKeyForm.NoTokens')}

; + }; + + const keyWithToken = apiKeys.find((k) => !!k.token); + + return ( +
+

{t('APIKeyForm.Summary')}

+ +
+

{t('APIKeyForm.CreateToken')}

+ + + { + setKeyLabel(event.target.value); + }} + placeholder={t('APIKeyForm.TokenPlaceholder')} + type="text" + value={keyLabel} + /> + + + + {keyWithToken && ( +
+

+ {t('APIKeyForm.NewTokenTitle')} +

+

+ {t('APIKeyForm.NewTokenInfo')} +

+ - - - - {keyWithToken && ( -
-

- {this.props.t('APIKeyForm.NewTokenTitle')} -

-

- {this.props.t('APIKeyForm.NewTokenInfo')} -

- -
- )} -
- -
-

- {this.props.t('APIKeyForm.ExistingTokensTitle')} -

- {this.renderApiKeys()} -
+
+ )}
- ); - } -} -APIKeyForm.propTypes = { - apiKeys: PropTypes.arrayOf(PropTypes.shape(APIKeyPropType)).isRequired, - createApiKey: PropTypes.func.isRequired, - removeApiKey: PropTypes.func.isRequired, - t: PropTypes.func.isRequired +
+

+ {t('APIKeyForm.ExistingTokensTitle')} +

+ {renderApiKeys()} +
+
+ ); }; export default APIKeyForm; diff --git a/client/modules/User/pages/AccountView.jsx b/client/modules/User/pages/AccountView.jsx index 9786f3e627..e9b3da7c9a 100644 --- a/client/modules/User/pages/AccountView.jsx +++ b/client/modules/User/pages/AccountView.jsx @@ -1,11 +1,10 @@ import React from 'react'; -import { useDispatch, useSelector } from 'react-redux'; +import { useSelector } from 'react-redux'; import { Tab, Tabs, TabList, TabPanel } from 'react-tabs'; import { Helmet } from 'react-helmet'; import { useTranslation } from 'react-i18next'; import { useHistory, useLocation } from 'react-router-dom'; import { parse } from 'query-string'; -import { createApiKey, removeApiKey } from '../actions'; import AccountForm from '../components/AccountForm'; import SocialAuthButton from '../components/SocialAuthButton'; import APIKeyForm from '../components/APIKeyForm'; @@ -51,9 +50,6 @@ function AccountView() { const showError = !!queryParams.error; const errorType = queryParams.error; const accessTokensUIEnabled = window.process.env.UI_ACCESS_TOKEN_ENABLED; - - const apiKeys = useSelector((state) => state.user.apiKeys); - const dispatch = useDispatch(); const history = useHistory(); return ( @@ -103,13 +99,7 @@ function AccountView() { - dispatch(createApiKey)} - removeApiKey={() => dispatch(removeApiKey)} - t={t} - /> + )}