MFA: shuffled components to avoid re-rendering closing the setup dialog

This commit is contained in:
gbuomprisco
2024-10-13 22:19:37 +08:00
parent fe2148730a
commit d137df2675
2 changed files with 93 additions and 97 deletions

View File

@@ -46,17 +46,25 @@ import { Trans } from '@kit/ui/trans';
import { MultiFactorAuthSetupDialog } from './multi-factor-auth-setup-dialog'; import { MultiFactorAuthSetupDialog } from './multi-factor-auth-setup-dialog';
const MAX_FACTOR_COUNT = 10;
export function MultiFactorAuthFactorsList(props: { userId: string }) { export function MultiFactorAuthFactorsList(props: { userId: string }) {
return (
<div className={'flex flex-col space-y-4'}>
<FactorsTableContainer userId={props.userId} />
<div>
<MultiFactorAuthSetupDialog userId={props.userId} />
</div>
</div>
);
}
function FactorsTableContainer(props: { userId: string }) {
const { const {
data: factors, data: factors,
isLoading, isLoading,
isError, isError,
} = useFetchAuthFactors(props.userId); } = useFetchAuthFactors(props.userId);
const [unEnrolling, setUnenrolling] = useState<string>();
if (isLoading) { if (isLoading) {
return ( return (
<div className={'flex items-center space-x-4'}> <div className={'flex items-center space-x-4'}>
@@ -103,37 +111,11 @@ export function MultiFactorAuthFactorsList(props: { userId: string }) {
<Trans i18nKey={'account:multiFactorAuthDescription'} /> <Trans i18nKey={'account:multiFactorAuthDescription'} />
</AlertDescription> </AlertDescription>
</Alert> </Alert>
<div>
<MultiFactorAuthSetupDialog userId={props.userId} />
</div>
</div> </div>
); );
} }
const canAddNewFactors = allFactors.length < MAX_FACTOR_COUNT; return <FactorsTable factors={allFactors} userId={props.userId} />;
return (
<div className={'flex flex-col space-y-4'}>
<FactorsTable factors={allFactors} setUnenrolling={setUnenrolling} />
<If condition={canAddNewFactors}>
<div>
<MultiFactorAuthSetupDialog userId={props.userId} />
</div>
</If>
<If condition={unEnrolling}>
{(factorId) => (
<ConfirmUnenrollFactorModal
userId={props.userId}
factorId={factorId}
setIsModalOpen={() => setUnenrolling(undefined)}
/>
)}
</If>
</div>
);
} }
function ConfirmUnenrollFactorModal( function ConfirmUnenrollFactorModal(
@@ -157,7 +139,7 @@ function ConfirmUnenrollFactorModal(
const errorCode = response.data; const errorCode = response.data;
throw t(`auth:errors.${errorCode}`, { throw t(`auth:errors.${errorCode}`, {
defaultValue: t(`account:unenrollFactorError`) defaultValue: t(`account:unenrollFactorError`),
}); });
} }
}); });
@@ -205,13 +187,16 @@ function ConfirmUnenrollFactorModal(
} }
function FactorsTable({ function FactorsTable({
setUnenrolling,
factors, factors,
userId,
}: React.PropsWithChildren<{ }: React.PropsWithChildren<{
setUnenrolling: (factorId: string) => void;
factors: Factor[]; factors: Factor[];
userId: string;
}>) { }>) {
const [unEnrolling, setUnenrolling] = useState<string>();
return ( return (
<>
<Table> <Table>
<TableHeader> <TableHeader>
<TableRow> <TableRow>
@@ -274,6 +259,17 @@ function FactorsTable({
))} ))}
</TableBody> </TableBody>
</Table> </Table>
<If condition={unEnrolling}>
{(factorId) => (
<ConfirmUnenrollFactorModal
userId={userId}
factorId={factorId}
setIsModalOpen={() => setUnenrolling(undefined)}
/>
)}
</If>
</>
); );
} }
@@ -291,13 +287,13 @@ function useUnenrollFactor(userId: string) {
return { return {
success: false as const, success: false as const,
data: error.code as string, data: error.code as string,
} };
} }
return { return {
success: true as const, success: true as const,
data, data,
} };
}; };
return useMutation({ return useMutation({

View File

@@ -53,7 +53,7 @@ export function MultiFactorAuthSetupDialog(props: { userId: string }) {
const onEnrollSuccess = useCallback(() => { const onEnrollSuccess = useCallback(() => {
setIsOpen(false); setIsOpen(false);
return toast.success(t(`multiFactorSetupSuccess`)); return toast.success(t(`account:multiFactorSetupSuccess`));
}, [t]); }, [t]);
return ( return (