Skip to content

Commit

Permalink
refactor(console): implement new jwt customizer delete modal
Browse files Browse the repository at this point in the history
implement new jwt customizer delete modal
  • Loading branch information
simeng-li committed Apr 19, 2024
1 parent c1301dd commit 142e8a5
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 28 deletions.
32 changes: 6 additions & 26 deletions packages/console/src/pages/CustomizeJwt/CustomizerItem/index.tsx
Original file line number Diff line number Diff line change
@@ -1,45 +1,23 @@
import { LogtoJwtTokenKeyType } from '@logto/schemas';
import { useCallback } from 'react';
import { useTranslation } from 'react-i18next';

import DeleteIcon from '@/assets/icons/delete.svg';
import EditIcon from '@/assets/icons/edit.svg';
import Button from '@/ds-components/Button';
import useApi from '@/hooks/use-api';
import { useConfirmModal } from '@/hooks/use-confirm-modal';
import useTenantPathname from '@/hooks/use-tenant-pathname';
import { getApiPath, getPagePath } from '@/pages/CustomizeJwt/utils/path';

import useJwtCustomizer from '../use-jwt-customizer';
import { getPagePath } from '@/pages/CustomizeJwt/utils/path';

import * as styles from './index.module.scss';

type Props = {
readonly tokenType: LogtoJwtTokenKeyType;
readonly onDelete: (token: LogtoJwtTokenKeyType) => void;
};

function CustomizerItem({ tokenType }: Props) {
function CustomizerItem({ tokenType, onDelete }: Props) {
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
const apiLink = getApiPath(tokenType);
const editLink = getPagePath(tokenType, 'edit');
const { navigate } = useTenantPathname();
const { show } = useConfirmModal();
const { mutate } = useJwtCustomizer();

const api = useApi();

const onDelete = useCallback(async () => {
const [confirm] = await show({
title: 'jwt_claims.delete_modal_title',
ModalContent: t('jwt_claims.delete_modal_content'),
confirmButtonText: 'general.delete',
});

if (confirm) {
await api.delete(apiLink);
await mutate();
}
}, [api, apiLink, mutate, show, t]);

return (
<div className={styles.container}>
Expand Down Expand Up @@ -67,7 +45,9 @@ function CustomizerItem({ tokenType }: Props) {
type="text"
size="small"
title="general.delete"
onClick={onDelete}
onClick={() => {
onDelete(tokenType);
}}
/>
</div>
</div>
Expand Down
58 changes: 58 additions & 0 deletions packages/console/src/pages/CustomizeJwt/DeleteConfirmModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { type LogtoJwtTokenKeyType } from '@logto/schemas';
import { useCallback, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useSWRConfig } from 'swr';

import ConfirmModal from '@/ds-components/ConfirmModal';
import useApi from '@/hooks/use-api';
import { getApiPath } from '@/pages/CustomizeJwt/utils/path';

type Props = {
readonly isOpen: boolean;
readonly tokenType?: LogtoJwtTokenKeyType;
readonly onCancel: () => void;
};

function DeleteConfirmModal({ isOpen, tokenType, onCancel }: Props) {
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
const [loading, setLoading] = useState(false);
const { mutate } = useSWRConfig();

const api = useApi();
const apiLink = tokenType && getApiPath(tokenType);

const onDelete = useCallback(async () => {
// If no token type is provided, dismiss the modal
if (!apiLink) {
onCancel();
return;
}

setLoading(true);

try {
// Delete the JWT customizer
await api.delete(apiLink);
// Mutate the SWR cache
await mutate(getApiPath());
} finally {
setLoading(false);
onCancel();
}
}, [api, apiLink, mutate, onCancel]);

return (
<ConfirmModal
title="jwt_claims.delete_modal_title"
confirmButtonText="general.delete"
isOpen={isOpen}
isLoading={loading}
onConfirm={onDelete}
onCancel={onCancel}
>
{t('jwt_claims.delete_modal_content')}
</ConfirmModal>
);
}

export default DeleteConfirmModal;
25 changes: 23 additions & 2 deletions packages/console/src/pages/CustomizeJwt/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { LogtoJwtTokenKeyType } from '@logto/schemas';
import { useCallback, useState } from 'react';
import { useTranslation } from 'react-i18next';

import FormCard, { FormCardSkeleton } from '@/components/FormCard';
Expand All @@ -7,12 +8,19 @@ import FormField from '@/ds-components/FormField';

import CreateButton from './CreateButton';
import CustomizerItem from './CustomizerItem';
import DeleteConfirmModal from './DeleteConfirmModal';
import * as styles from './index.module.scss';
import useJwtCustomizer from './use-jwt-customizer';

function CustomizeJwt() {
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });

const [deleteModalTokenType, setDeleteModalTokenType] = useState<LogtoJwtTokenKeyType>();

const onDeleteHandler = useCallback((tokenType: LogtoJwtTokenKeyType) => {
setDeleteModalTokenType(tokenType);
}, []);

const { isLoading, accessTokenJwtCustomizer, clientCredentialsJwtCustomizer } =
useJwtCustomizer();

Expand All @@ -38,7 +46,10 @@ function CustomizeJwt() {
{t('jwt_claims.user_jwt.card_description')}
</div>
{accessTokenJwtCustomizer ? (
<CustomizerItem tokenType={LogtoJwtTokenKeyType.AccessToken} />
<CustomizerItem
tokenType={LogtoJwtTokenKeyType.AccessToken}
onDelete={onDeleteHandler}
/>
) : (
<CreateButton tokenType={LogtoJwtTokenKeyType.AccessToken} />
)}
Expand All @@ -50,7 +61,10 @@ function CustomizeJwt() {
{t('jwt_claims.machine_to_machine_jwt.card_description')}
</div>
{clientCredentialsJwtCustomizer ? (
<CustomizerItem tokenType={LogtoJwtTokenKeyType.ClientCredentials} />
<CustomizerItem
tokenType={LogtoJwtTokenKeyType.ClientCredentials}
onDelete={onDeleteHandler}
/>
) : (
<CreateButton tokenType={LogtoJwtTokenKeyType.ClientCredentials} />
)}
Expand All @@ -59,6 +73,13 @@ function CustomizeJwt() {
</>
)}
</div>
<DeleteConfirmModal
isOpen={!!deleteModalTokenType}
tokenType={deleteModalTokenType}
onCancel={() => {
setDeleteModalTokenType(undefined);
}}
/>
</main>
);
}
Expand Down

0 comments on commit 142e8a5

Please sign in to comment.