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:
parent
00c2581668
commit
f0bbc2a1f4
2 changed files with 105 additions and 3 deletions
|
@ -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;
|
|
@ -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 { useMemo, useState } from 'react';
|
||||||
import { Trans, useTranslation } from 'react-i18next';
|
import { Trans, useTranslation } from 'react-i18next';
|
||||||
import useSWR from 'swr';
|
import useSWR from 'swr';
|
||||||
|
@ -16,6 +16,7 @@ import TextLink from '@/ds-components/TextLink';
|
||||||
import useApi, { type RequestError } from '@/hooks/use-api';
|
import useApi, { type RequestError } from '@/hooks/use-api';
|
||||||
|
|
||||||
import CreateTokenModal from './CreateTokenModal';
|
import CreateTokenModal from './CreateTokenModal';
|
||||||
|
import EditTokenModal from './EditTokenModal';
|
||||||
import styles from './index.module.scss';
|
import styles from './index.module.scss';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
|
@ -29,6 +30,7 @@ function PersonalAccessTokens({ userId }: Props) {
|
||||||
`api/users/${userId}/personal-access-tokens`
|
`api/users/${userId}/personal-access-tokens`
|
||||||
);
|
);
|
||||||
const api = useApi();
|
const api = useApi();
|
||||||
|
const [editToken, setEditToken] = useState<PersonalAccessToken>();
|
||||||
|
|
||||||
const tableColumns: Array<Column<Token>> = useMemo(
|
const tableColumns: Array<Column<Token>> = useMemo(
|
||||||
() => [
|
() => [
|
||||||
|
@ -61,16 +63,19 @@ function PersonalAccessTokens({ userId }: Props) {
|
||||||
{
|
{
|
||||||
title: '',
|
title: '',
|
||||||
dataIndex: 'actions',
|
dataIndex: 'actions',
|
||||||
render: ({ name }) => (
|
render: (token) => (
|
||||||
<ActionsButton
|
<ActionsButton
|
||||||
fieldName="user_details.personal_access_tokens.title_short"
|
fieldName="user_details.personal_access_tokens.title_short"
|
||||||
deleteConfirmation="user_details.personal_access_tokens.delete_confirmation"
|
deleteConfirmation="user_details.personal_access_tokens.delete_confirmation"
|
||||||
onDelete={async () => {
|
onDelete={async () => {
|
||||||
await api.delete(
|
await api.delete(
|
||||||
`api/users/${userId}/personal-access-tokens/${encodeURIComponent(name)}`
|
`api/users/${userId}/personal-access-tokens/${encodeURIComponent(token.name)}`
|
||||||
);
|
);
|
||||||
void mutate();
|
void mutate();
|
||||||
}}
|
}}
|
||||||
|
onEdit={() => {
|
||||||
|
setEditToken(token);
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
@ -144,6 +149,18 @@ function PersonalAccessTokens({ userId }: Props) {
|
||||||
void mutate();
|
void mutate();
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
{editToken && (
|
||||||
|
<EditTokenModal
|
||||||
|
userId={userId}
|
||||||
|
token={editToken}
|
||||||
|
onClose={(updated) => {
|
||||||
|
if (updated) {
|
||||||
|
void mutate();
|
||||||
|
}
|
||||||
|
setEditToken(undefined);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</FormField>
|
</FormField>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue