mirror of
https://gitee.com/baidu/amis.git
synced 2024-12-04 21:08:55 +08:00
Merge remote-tracking branch 'baidu/master'
This commit is contained in:
commit
a987738a58
@ -17,6 +17,13 @@ export default function ButtonExamples() {
|
||||
setIsShow(false);
|
||||
}, []);
|
||||
|
||||
async function handleValidate() {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
// setTimeout(() => reject('error message'), 200);
|
||||
setTimeout(() => resolve(), 200);
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="wrapper">
|
||||
<Button onClick={handleClick}>Open</Button>
|
||||
@ -29,7 +36,7 @@ export default function ButtonExamples() {
|
||||
onCancel={handleCancel}
|
||||
>
|
||||
{({bodyRef}) => (
|
||||
<Form ref={bodyRef}>
|
||||
<Form ref={bodyRef} onValidate={handleValidate}>
|
||||
{({control}) => (
|
||||
<>
|
||||
<Controller
|
||||
|
@ -3,6 +3,7 @@ import Modal from './Modal';
|
||||
import Button from './Button';
|
||||
import Drawer from './Drawer';
|
||||
import {localeable, LocaleProps, themeable, ThemeProps} from 'amis-core';
|
||||
import Spinner from './Spinner';
|
||||
|
||||
export interface ConfirmBoxProps extends LocaleProps, ThemeProps {
|
||||
show?: boolean;
|
||||
@ -56,19 +57,32 @@ export function ConfirmBox({
|
||||
bodyClassName,
|
||||
footerClassName
|
||||
}: ConfirmBoxProps) {
|
||||
const [loading, setLoading] = React.useState<boolean>();
|
||||
const [error, setError] = React.useState<string>();
|
||||
const bodyRef = React.useRef<
|
||||
{submit: () => Promise<Record<string, any>>} | undefined
|
||||
>();
|
||||
const handleConfirm = React.useCallback(async () => {
|
||||
const ret = beforeConfirm
|
||||
? await beforeConfirm?.(bodyRef.current)
|
||||
: await bodyRef.current?.submit?.();
|
||||
setError('');
|
||||
setLoading(true);
|
||||
try {
|
||||
const ret = beforeConfirm
|
||||
? await beforeConfirm?.(bodyRef.current)
|
||||
: await bodyRef.current?.submit?.();
|
||||
|
||||
if (ret === false) {
|
||||
return;
|
||||
if (ret === false) {
|
||||
return;
|
||||
} else if (typeof ret === 'string') {
|
||||
setError(ret);
|
||||
return;
|
||||
}
|
||||
|
||||
onConfirm?.(ret);
|
||||
} catch (e) {
|
||||
setError(e.message);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
onConfirm?.(ret);
|
||||
}, [onConfirm, beforeConfirm]);
|
||||
|
||||
function renderDialog() {
|
||||
@ -95,6 +109,14 @@ export function ConfirmBox({
|
||||
</Modal.Body>
|
||||
{showFooter ?? true ? (
|
||||
<Modal.Footer className={footerClassName}>
|
||||
{loading || error ? (
|
||||
<div className={cx('Dialog-info')}>
|
||||
<Spinner size="sm" key="info" show={loading} />
|
||||
{error ? (
|
||||
<span className={cx('Dialog-error')}>{error}</span>
|
||||
) : null}
|
||||
</div>
|
||||
) : null}
|
||||
<Button onClick={onCancel}>{__('cancel')}</Button>
|
||||
<Button onClick={handleConfirm} level="primary">
|
||||
{__('confirm')}
|
||||
@ -132,6 +154,14 @@ export function ConfirmBox({
|
||||
</div>
|
||||
{showFooter ?? true ? (
|
||||
<div className={cx('Drawer-footer', footerClassName)}>
|
||||
{loading || error ? (
|
||||
<div className={cx('Drawer-info')}>
|
||||
<Spinner size="sm" key="info" show={loading} />
|
||||
{error ? (
|
||||
<span className={cx('Drawer-error')}>{error}</span>
|
||||
) : null}
|
||||
</div>
|
||||
) : null}
|
||||
<Button onClick={handleConfirm} level="primary">
|
||||
{__('confirm')}
|
||||
</Button>
|
||||
|
@ -18,6 +18,7 @@ export type FormRef = React.MutableRefObject<
|
||||
export interface FormProps extends ThemeProps, LocaleProps {
|
||||
defaultValue?: any;
|
||||
autoSubmit?: boolean;
|
||||
onValidate?: (errors: any, values: any) => Promise<void>;
|
||||
onSubmit?: (value: any) => void;
|
||||
forwardRef?: FormRef;
|
||||
children?: (
|
||||
@ -32,7 +33,7 @@ export function Form(props: FormProps) {
|
||||
const {classnames: cx, className, autoSubmit} = props;
|
||||
const methods = useForm({
|
||||
defaultValues: props.defaultValue,
|
||||
resolver: useValidationResolver(props.translate)
|
||||
resolver: useValidationResolver(props.translate, props.onValidate)
|
||||
});
|
||||
let onSubmit = React.useRef<(data: any) => void>(
|
||||
methods.handleSubmit(props.onSubmit || noop)
|
||||
@ -66,7 +67,7 @@ export function Form(props: FormProps) {
|
||||
props.onSubmit?.(values);
|
||||
resolve(values);
|
||||
},
|
||||
() => resolve(false)
|
||||
e => resolve(e.customValidate?.message || false)
|
||||
)();
|
||||
})
|
||||
};
|
||||
|
@ -19,7 +19,20 @@ function formatErrors(errors: any) {
|
||||
return formated;
|
||||
}
|
||||
|
||||
export function useValidationResolver(__ = (str: string) => str) {
|
||||
export function useValidationResolver(
|
||||
__ = (str: string) => str,
|
||||
validate?: (
|
||||
error: {
|
||||
[propName: string]: {
|
||||
rule: string;
|
||||
msg: string;
|
||||
}[];
|
||||
},
|
||||
values: Record<string, any>,
|
||||
context: any,
|
||||
config: any
|
||||
) => Promise<void>
|
||||
) {
|
||||
return React.useCallback<any>(
|
||||
async (values: any, context: any, config: any) => {
|
||||
const rules: any = {};
|
||||
@ -53,12 +66,23 @@ export function useValidationResolver(__ = (str: string) => str) {
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
await validate?.(errors, values, context, config);
|
||||
} catch (e) {
|
||||
errors.customValidate = [
|
||||
{
|
||||
rule: 'custom',
|
||||
msg: e.message || e
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
return {
|
||||
values,
|
||||
errors: formatErrors(errors)
|
||||
};
|
||||
},
|
||||
[__]
|
||||
[__, validate]
|
||||
);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user