0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2025-03-24 22:41:28 -05:00

refactor(console): the submit state of forms (#455)

This commit is contained in:
Xiao Yijun 2022-03-29 12:58:53 +08:00 committed by GitHub
parent d557d9b65c
commit 58ab342c47
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 84 additions and 98 deletions

View file

@ -1,6 +1,7 @@
import { Resource } from '@logto/schemas';
import React, { useEffect, useState } from 'react';
import { useForm } from 'react-hook-form';
import { toast } from 'react-hot-toast';
import { useTranslation } from 'react-i18next';
import Modal from 'react-modal';
import { useLocation, useParams } from 'react-router-dom';
@ -37,10 +38,15 @@ const ApiResourceDetails = () => {
const { data, error, mutate } = useSWR<Resource, RequestError>(id && `/api/resources/${id}`);
const isLoading = !data && !error;
const { handleSubmit, register, reset } = useForm<FormData>({
const {
handleSubmit,
register,
reset,
formState: { isSubmitting },
} = useForm<FormData>({
defaultValues: data,
});
const [submitting, setSubmitting] = useState(false);
const api = useApi();
const [isDeleteFormOpen, setIsDeleteFormOpen] = useState(false);
@ -54,21 +60,15 @@ const ApiResourceDetails = () => {
}, [data, reset]);
const onSubmit = handleSubmit(async (formData) => {
if (!data || submitting) {
if (!data || isSubmitting) {
return;
}
setSubmitting(true);
try {
const updatedApiResource = await api
.patch(`/api/resources/${data.id}`, { json: formData })
.json<Resource>();
void mutate(updatedApiResource);
} catch (error: unknown) {
console.error(error);
} finally {
setSubmitting(false);
}
const updatedApiResource = await api
.patch(`/api/resources/${data.id}`, { json: formData })
.json<Resource>();
void mutate(updatedApiResource);
toast.success(t('api_resource_details.save_success'));
});
return (
@ -157,7 +157,7 @@ const ApiResourceDetails = () => {
</div>
<div className={styles.submit}>
<Button
disabled={submitting}
disabled={isSubmitting}
htmlType="submit"
type="primary"
title="admin_console.api_resource_details.save_changes"

View file

@ -1,5 +1,5 @@
import { Resource } from '@logto/schemas';
import React, { useState } from 'react';
import React from 'react';
import { useForm } from 'react-hook-form';
import Button from '@/components/Button';
@ -18,23 +18,21 @@ type Props = {
};
const CreateForm = ({ onClose }: Props) => {
const { handleSubmit, register } = useForm<FormData>();
const [loading, setLoading] = useState(false);
const {
handleSubmit,
register,
formState: { isSubmitting },
} = useForm<FormData>();
const api = useApi();
const onSubmit = handleSubmit(async (data) => {
if (loading) {
if (isSubmitting) {
return;
}
setLoading(true);
try {
const createdApiResource = await api.post('/api/resources', { json: data }).json<Resource>();
onClose?.(createdApiResource);
} finally {
setLoading(false);
}
const createdApiResource = await api.post('/api/resources', { json: data }).json<Resource>();
onClose?.(createdApiResource);
});
return (
@ -43,7 +41,7 @@ const CreateForm = ({ onClose }: Props) => {
subtitle="api_resources.subtitle"
footer={
<Button
disabled={loading}
disabled={isSubmitting}
htmlType="submit"
title="admin_console.api_resources.create"
size="large"

View file

@ -52,9 +52,14 @@ const ApplicationDetails = () => {
const [isDeleteFormOpen, setIsDeleteFormOpen] = useState(false);
const api = useApi();
const [submitting, setSubmitting] = useState(false);
const { control, handleSubmit, register, reset } = useForm<Application>();
const {
control,
handleSubmit,
register,
reset,
formState: { isSubmitting },
} = useForm<Application>();
useEffect(() => {
if (!data) {
@ -81,20 +86,15 @@ const ApplicationDetails = () => {
});
const onSubmit = handleSubmit(async (formData) => {
if (!data || submitting) {
if (!data || isSubmitting) {
return;
}
setSubmitting(true);
try {
const updatedApplication = await api
.patch(`/api/applications/${data.id}`, { json: formData })
.json<Application>();
void mutate(updatedApplication);
toast.success(t('application_details.save_success'));
} finally {
setSubmitting(false);
}
const updatedApplication = await api
.patch(`/api/applications/${data.id}`, { json: formData })
.json<Application>();
void mutate(updatedApplication);
toast.success(t('application_details.save_success'));
});
const isAdvancedSettings = location.pathname.includes('advanced-settings');
@ -236,7 +236,7 @@ const ApplicationDetails = () => {
</div>
<div className={styles.submit}>
<Button
disabled={submitting}
disabled={isSubmitting}
htmlType="submit"
type="primary"
title="admin_console.application_details.save_changes"

View file

@ -35,7 +35,7 @@ const CreateForm = ({ onClose }: Props) => {
handleSubmit,
control,
register,
formState: { errors },
formState: { errors, isSubmitting },
} = useForm<FormData>();
const {
field: { onChange, value, name, ref },
@ -43,7 +43,6 @@ const CreateForm = ({ onClose }: Props) => {
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
const { data: setting } = useSWR<Setting, RequestError>('/api/settings');
const api = useApi();
const [loading, setLoading] = useState(false);
const isGetStartedSkipped = setting?.adminConsole.applicationSkipGetStarted;
@ -53,23 +52,17 @@ const CreateForm = ({ onClose }: Props) => {
};
const onSubmit = handleSubmit(async (data) => {
if (loading) {
if (isSubmitting) {
return;
}
setLoading(true);
const createdApp = await api.post('/api/applications', { json: data }).json<Application>();
setCreatedApp(createdApp);
try {
const createdApp = await api.post('/api/applications', { json: data }).json<Application>();
setCreatedApp(createdApp);
if (isGetStartedSkipped) {
closeModal();
} else {
setIsQuickStartGuideOpen(true);
}
} finally {
setLoading(false);
if (isGetStartedSkipped) {
closeModal();
} else {
setIsQuickStartGuideOpen(true);
}
});
@ -80,7 +73,7 @@ const CreateForm = ({ onClose }: Props) => {
size="large"
footer={
<Button
disabled={loading}
disabled={isSubmitting}
htmlType="submit"
title="admin_console.applications.create"
size="large"

View file

@ -1,5 +1,5 @@
import { User } from '@logto/schemas';
import React, { useState } from 'react';
import React from 'react';
import { useForm } from 'react-hook-form';
import { toast } from 'react-hot-toast';
import { useTranslation } from 'react-i18next';
@ -23,21 +23,17 @@ const ResetPasswordForm = ({ onClose, userId }: Props) => {
const { t } = useTranslation(undefined, {
keyPrefix: 'admin_console',
});
const { handleSubmit, register } = useForm<FormData>();
const {
handleSubmit,
register,
formState: { isSubmitting },
} = useForm<FormData>();
const api = useApi();
const [loading, setLoading] = useState(false);
const onSubmit = handleSubmit(async (data) => {
setLoading(true);
try {
await api.patch(`/api/users/${userId}/password`, { json: data }).json<User>();
onClose?.();
toast.success(t('user_details.reset_password.reset_password_success'));
} finally {
setLoading(false);
}
await api.patch(`/api/users/${userId}/password`, { json: data }).json<User>();
onClose?.();
toast.success(t('user_details.reset_password.reset_password_success'));
});
return (
@ -45,7 +41,7 @@ const ResetPasswordForm = ({ onClose, userId }: Props) => {
title="user_details.reset_password.title"
footer={
<Button
disabled={loading}
disabled={isSubmitting}
htmlType="submit"
title="admin_console.user_details.reset_password.reset_password"
size="large"

View file

@ -50,8 +50,14 @@ const UserDetails = () => {
const { data, error, mutate } = useSWR<User, RequestError>(id && `/api/users/${id}`);
const isLoading = !data && !error;
const { handleSubmit, register, control, reset } = useForm<FormData>();
const [submitting, setSubmitting] = useState(false);
const {
handleSubmit,
register,
control,
reset,
formState: { isSubmitting },
} = useForm<FormData>();
const {
field: { onChange, value },
} = useController({ name: 'customData', control, rules: { required: true } });
@ -69,7 +75,7 @@ const UserDetails = () => {
}, [data, reset]);
const onSubmit = handleSubmit(async (formData) => {
if (!data || submitting) {
if (!data || isSubmitting) {
return;
}
@ -86,15 +92,10 @@ const UserDetails = () => {
avatar: formData.avatar,
customData,
};
setSubmitting(true);
try {
const updatedUser = await api.patch(`/api/users/${data.id}`, { json: payload }).json<User>();
void mutate(updatedUser);
toast.success(t('user_details.saved'));
} finally {
setSubmitting(false);
}
const updatedUser = await api.patch(`/api/users/${data.id}`, { json: payload }).json<User>();
void mutate(updatedUser);
toast.success(t('user_details.saved'));
});
return (
@ -227,7 +228,7 @@ const UserDetails = () => {
</div>
<div className={styles.submit}>
<Button
disabled={submitting}
disabled={isSubmitting}
htmlType="submit"
type="primary"
title="admin_console.user_details.save_changes"

View file

@ -1,5 +1,5 @@
import { User } from '@logto/schemas';
import React, { useState } from 'react';
import React from 'react';
import { useForm } from 'react-hook-form';
import Button from '@/components/Button';
@ -19,24 +19,20 @@ type Props = {
};
const CreateForm = ({ onClose }: Props) => {
const { handleSubmit, register } = useForm<FormData>();
const {
handleSubmit,
register,
formState: { isSubmitting },
} = useForm<FormData>();
const api = useApi();
const [loading, setLoading] = useState(false);
const onSubmit = handleSubmit(async (data) => {
if (loading) {
if (isSubmitting) {
return;
}
setLoading(true);
try {
const createdUser = await api.post('/api/users', { json: data }).json<User>();
onClose?.(createdUser, btoa(data.password));
} finally {
setLoading(false);
}
const createdUser = await api.post('/api/users', { json: data }).json<User>();
onClose?.(createdUser, btoa(data.password));
});
return (
@ -45,7 +41,7 @@ const CreateForm = ({ onClose }: Props) => {
subtitle="users.subtitle"
footer={
<Button
disabled={loading}
disabled={isSubmitting}
htmlType="submit"
title="admin_console.users.create"
size="large"

View file

@ -151,6 +151,7 @@ const translation = {
cancel: 'Cancel',
delete: 'Delete',
api_resource_deleted: 'The API Resource {{name}} deleted.',
save_success: 'Saved!',
},
connectors: {
title: 'Connectors',

View file

@ -151,6 +151,7 @@ const translation = {
cancel: 'Cancel',
delete: 'Delete',
api_resource_deleted: 'The API Resource {{name}} deleted.',
save_success: 'Saved!',
},
connectors: {
title: '连接器',