0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2025-02-17 22:04:19 -05:00

feat(console): edit personal access token name (#6491)

This commit is contained in:
wangsijie 2024-08-22 11:30:58 +08:00 committed by GitHub
parent 00c2581668
commit f0bbc2a1f4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 105 additions and 3 deletions

View file

@ -0,0 +1,85 @@
import { type PersonalAccessToken } from '@logto/schemas';
import { useCallback } from 'react';
import { useForm } from 'react-hook-form';
import { toast } from 'react-hot-toast';
import { useTranslation } from 'react-i18next';
import ReactModal from 'react-modal';
import Button from '@/ds-components/Button';
import FormField from '@/ds-components/FormField';
import ModalLayout from '@/ds-components/ModalLayout';
import TextInput from '@/ds-components/TextInput';
import useApi from '@/hooks/use-api';
import modalStyles from '@/scss/modal.module.scss';
import { trySubmitSafe } from '@/utils/form';
type FormData = { name: string; expiration: string };
type Props = {
readonly userId: string;
readonly token: PersonalAccessToken;
readonly onClose: (updated: boolean) => void;
};
function EditTokenModal({ userId, token, onClose }: Props) {
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
const {
register,
formState: { errors, isSubmitting },
handleSubmit,
reset,
} = useForm<FormData>({ defaultValues: { name: token.name } });
const onCloseHandler = useCallback(
(updated?: boolean) => {
reset();
onClose(updated ?? false);
},
[onClose, reset]
);
const api = useApi();
const submit = handleSubmit(
trySubmitSafe(async (data) => {
const createdData = await api
.patch(`api/users/${userId}/personal-access-tokens/${encodeURIComponent(token.name)}`, {
json: data,
})
.json<PersonalAccessToken>();
toast.success(
t('user_details.personal_access_tokens.edit_modal.edited', { name: createdData.name })
);
onCloseHandler(true);
})
);
return (
<ReactModal
isOpen
className={modalStyles.content}
overlayClassName={modalStyles.overlay}
onRequestClose={() => {
onCloseHandler();
}}
>
<ModalLayout
title="user_details.personal_access_tokens.edit_modal.title"
footer={
<Button type="primary" title="general.save" isLoading={isSubmitting} onClick={submit} />
}
onClose={onCloseHandler}
>
<FormField isRequired title="general.name">
<TextInput
// eslint-disable-next-line jsx-a11y/no-autofocus
autoFocus
placeholder="My token"
error={Boolean(errors.name)}
{...register('name', { required: true })}
/>
</FormField>
</ModalLayout>
</ReactModal>
);
}
export default EditTokenModal;

View file

@ -1,4 +1,4 @@
import { type PersonalAccessToken as Token } from '@logto/schemas';
import { type PersonalAccessToken, type PersonalAccessToken as Token } from '@logto/schemas';
import { useMemo, useState } from 'react';
import { Trans, useTranslation } from 'react-i18next';
import useSWR from 'swr';
@ -16,6 +16,7 @@ import TextLink from '@/ds-components/TextLink';
import useApi, { type RequestError } from '@/hooks/use-api';
import CreateTokenModal from './CreateTokenModal';
import EditTokenModal from './EditTokenModal';
import styles from './index.module.scss';
type Props = {
@ -29,6 +30,7 @@ function PersonalAccessTokens({ userId }: Props) {
`api/users/${userId}/personal-access-tokens`
);
const api = useApi();
const [editToken, setEditToken] = useState<PersonalAccessToken>();
const tableColumns: Array<Column<Token>> = useMemo(
() => [
@ -61,16 +63,19 @@ function PersonalAccessTokens({ userId }: Props) {
{
title: '',
dataIndex: 'actions',
render: ({ name }) => (
render: (token) => (
<ActionsButton
fieldName="user_details.personal_access_tokens.title_short"
deleteConfirmation="user_details.personal_access_tokens.delete_confirmation"
onDelete={async () => {
await api.delete(
`api/users/${userId}/personal-access-tokens/${encodeURIComponent(name)}`
`api/users/${userId}/personal-access-tokens/${encodeURIComponent(token.name)}`
);
void mutate();
}}
onEdit={() => {
setEditToken(token);
}}
/>
),
},
@ -144,6 +149,18 @@ function PersonalAccessTokens({ userId }: Props) {
void mutate();
}}
/>
{editToken && (
<EditTokenModal
userId={userId}
token={editToken}
onClose={(updated) => {
if (updated) {
void mutate();
}
setEditToken(undefined);
}}
/>
)}
</FormField>
);
}