|
@@ -2,14 +2,93 @@ import React, { useCallback } from 'react';
|
|
|
|
|
|
|
|
import { useTranslation } from 'next-i18next';
|
|
import { useTranslation } from 'next-i18next';
|
|
|
|
|
|
|
|
-import { apiv3Delete, apiv3Get, apiv3Post } from '~/client/util/apiv3-client';
|
|
|
|
|
|
|
+import {
|
|
|
|
|
+ apiv3Delete, apiv3Get, apiv3Post, apiv3Put,
|
|
|
|
|
+} from '~/client/util/apiv3-client';
|
|
|
import { toastSuccess, toastError } from '~/client/util/toastr';
|
|
import { toastSuccess, toastError } from '~/client/util/toastr';
|
|
|
|
|
+import { usePersonalSettings, useSWRxPersonalSettings } from '~/stores/personal-settings';
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+const ApiTokenSettings = React.memo((): JSX.Element => {
|
|
|
|
|
+
|
|
|
|
|
+ const { t } = useTranslation();
|
|
|
|
|
+ const { mutate: mutateDatabaseData } = useSWRxPersonalSettings();
|
|
|
|
|
+ const { data: personalSettingsData } = usePersonalSettings();
|
|
|
|
|
+
|
|
|
|
|
+ const submitHandler = useCallback(async() => {
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ await apiv3Put('/personal-setting/api-token');
|
|
|
|
|
+ mutateDatabaseData();
|
|
|
|
|
+
|
|
|
|
|
+ toastSuccess(t('toaster.update_successed', { target: t('page_me_apitoken.api_token'), ns: 'commons' }));
|
|
|
|
|
+ }
|
|
|
|
|
+ catch (err) {
|
|
|
|
|
+ toastError(err);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ }, [mutateDatabaseData, t]); return (
|
|
|
|
|
+ <>
|
|
|
|
|
+ <div className="row mb-3">
|
|
|
|
|
+ <label htmlFor="apiToken" className="col-md-3 text-md-end col-form-label">{t('Current API Token')}</label>
|
|
|
|
|
+ <div className="col-md-6">
|
|
|
|
|
+ {personalSettingsData?.apiToken != null
|
|
|
|
|
+ ? (
|
|
|
|
|
+ <input
|
|
|
|
|
+ data-testid="grw-api-settings-input"
|
|
|
|
|
+ data-vrt-blackout
|
|
|
|
|
+ className="form-control"
|
|
|
|
|
+ type="text"
|
|
|
|
|
+ name="apiToken"
|
|
|
|
|
+ value={personalSettingsData.apiToken}
|
|
|
|
|
+ readOnly
|
|
|
|
|
+ />
|
|
|
|
|
+ )
|
|
|
|
|
+ : (
|
|
|
|
|
+ <p>
|
|
|
|
|
+ { t('page_me_apitoken.notice.apitoken_issued') }
|
|
|
|
|
+ </p>
|
|
|
|
|
+ )}
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ <div className="row">
|
|
|
|
|
+ <div className="offset-lg-2 col-lg-7">
|
|
|
|
|
+
|
|
|
|
|
+ <p className="alert alert-warning">
|
|
|
|
|
+ { t('page_me_apitoken.notice.update_token1') }<br />
|
|
|
|
|
+ { t('page_me_apitoken.notice.update_token2') }
|
|
|
|
|
+ </p>
|
|
|
|
|
+
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <div className="row my-3">
|
|
|
|
|
+ <div className="offset-4 col-5">
|
|
|
|
|
+ <button
|
|
|
|
|
+ data-testid="grw-api-settings-update-button"
|
|
|
|
|
+ type="button"
|
|
|
|
|
+ className="btn btn-primary text-nowrap"
|
|
|
|
|
+ onClick={submitHandler}
|
|
|
|
|
+ >
|
|
|
|
|
+ {t('Update API Token')}
|
|
|
|
|
+ </button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ </>
|
|
|
|
|
+
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+});
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* TODO: support managing multiple access tokens.
|
|
* TODO: support managing multiple access tokens.
|
|
|
*/
|
|
*/
|
|
|
-const ApiSettings = React.memo((): JSX.Element => {
|
|
|
|
|
|
|
+const AccessTokenSettings = React.memo((): JSX.Element => {
|
|
|
|
|
|
|
|
const { t } = useTranslation();
|
|
const { t } = useTranslation();
|
|
|
const [accessToken, setAccessToken] = React.useState<string | null>(null);
|
|
const [accessToken, setAccessToken] = React.useState<string | null>(null);
|
|
@@ -22,7 +101,7 @@ const ApiSettings = React.memo((): JSX.Element => {
|
|
|
const result = await apiv3Post('/personal-setting/access-token', { expiredAt });
|
|
const result = await apiv3Post('/personal-setting/access-token', { expiredAt });
|
|
|
setAccessToken(result.data.token);
|
|
setAccessToken(result.data.token);
|
|
|
|
|
|
|
|
- toastSuccess(t('toaster.update_successed', { target: t('page_me_apitoken.api_token'), ns: 'commons' }));
|
|
|
|
|
|
|
+ toastSuccess(t('toaster.update_successed', { target: t('page_me_access_token.access_token'), ns: 'commons' }));
|
|
|
}
|
|
}
|
|
|
catch (err) {
|
|
catch (err) {
|
|
|
toastError(err);
|
|
toastError(err);
|
|
@@ -46,11 +125,8 @@ const ApiSettings = React.memo((): JSX.Element => {
|
|
|
|
|
|
|
|
return (
|
|
return (
|
|
|
<>
|
|
<>
|
|
|
-
|
|
|
|
|
- <h2 className="border-bottom pb-2 my-4 fs-4">{ t('API Token Settings') }</h2>
|
|
|
|
|
-
|
|
|
|
|
<div className="row mb-3">
|
|
<div className="row mb-3">
|
|
|
- <label htmlFor="apiToken" className="col-md-3 text-md-end col-form-label">{t('Current API Token')}</label>
|
|
|
|
|
|
|
+ <label htmlFor="apiToken" className="col-md-3 text-md-end col-form-label">{t('Current Access Token')}</label>
|
|
|
<div className="col-md-6">
|
|
<div className="col-md-6">
|
|
|
{accessToken != null
|
|
{accessToken != null
|
|
|
? (
|
|
? (
|
|
@@ -66,7 +142,7 @@ const ApiSettings = React.memo((): JSX.Element => {
|
|
|
)
|
|
)
|
|
|
: (
|
|
: (
|
|
|
<p>
|
|
<p>
|
|
|
- { t('page_me_apitoken.notice.apitoken_issued') }
|
|
|
|
|
|
|
+ { t('page_me_access_token.notice.access_token_issued') }
|
|
|
</p>
|
|
</p>
|
|
|
)}
|
|
)}
|
|
|
</div>
|
|
</div>
|
|
@@ -77,8 +153,8 @@ const ApiSettings = React.memo((): JSX.Element => {
|
|
|
<div className="offset-lg-2 col-lg-7">
|
|
<div className="offset-lg-2 col-lg-7">
|
|
|
|
|
|
|
|
<p className="alert alert-warning">
|
|
<p className="alert alert-warning">
|
|
|
- { t('page_me_apitoken.notice.update_token1') }<br />
|
|
|
|
|
- { t('page_me_apitoken.notice.update_token2') }
|
|
|
|
|
|
|
+ { t('page_me_access_token.notice.update_token1') }<br />
|
|
|
|
|
+ { t('page_me_access_token.notice.update_token2') }
|
|
|
</p>
|
|
</p>
|
|
|
|
|
|
|
|
</div>
|
|
</div>
|
|
@@ -92,15 +168,27 @@ const ApiSettings = React.memo((): JSX.Element => {
|
|
|
className="btn btn-primary text-nowrap"
|
|
className="btn btn-primary text-nowrap"
|
|
|
onClick={submitHandler}
|
|
onClick={submitHandler}
|
|
|
>
|
|
>
|
|
|
- {t('Update API Token')}
|
|
|
|
|
|
|
+ {t('Update Access Token')}
|
|
|
</button>
|
|
</button>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
-
|
|
|
|
|
</>
|
|
</>
|
|
|
-
|
|
|
|
|
);
|
|
);
|
|
|
|
|
+});
|
|
|
|
|
+
|
|
|
|
|
+const ApiSettings = React.memo((): JSX.Element => {
|
|
|
|
|
+
|
|
|
|
|
+ const { t } = useTranslation();
|
|
|
|
|
|
|
|
|
|
+ return (
|
|
|
|
|
+ <>
|
|
|
|
|
+ <h3 className="border-bottom pb-2 my-4 fs-5">{ t('API Token Settings') }</h3>
|
|
|
|
|
+ <ApiTokenSettings />
|
|
|
|
|
+
|
|
|
|
|
+ <h3 className="border-bottom pb-2 my-4 fs-5">{ t('Access Token Settings') }</h3>
|
|
|
|
|
+ <AccessTokenSettings />
|
|
|
|
|
+ </>
|
|
|
|
|
+ );
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
ApiSettings.displayName = 'ApiSettings';
|
|
ApiSettings.displayName = 'ApiSettings';
|