Feat: from values changed when unsaved will prompt (#351)
* fix: thumbnail image in kanban card (#338) * fix: thumbnail image in kanban card * Update attachment.ts * Update Kanban.Card.Designer.tsx Co-authored-by: chenos <chenlinxh@gmail.com> * feat: data unsaved will be prompt when close drawer * feat: data unsaved will be prompt when close drawer Co-authored-by: chenos <chenlinxh@gmail.com>
This commit is contained in:
parent
4e43e883ad
commit
4aa6de97e0
@ -285,4 +285,7 @@ export default {
|
||||
// workflows
|
||||
'Execution History': 'History',
|
||||
'Parallel branch': 'Branch',
|
||||
|
||||
'Confirm': 'Confirm',
|
||||
'Form value changed tip': 'Are you sure to exit that Data unsaved',
|
||||
}
|
||||
|
@ -477,5 +477,7 @@ export default {
|
||||
'Please select collection first': '请先选择数据表',
|
||||
'Only update records matching conditions': '只更新满足条件的数据',
|
||||
'Fields that are not assigned a value will be set to the default value, and those that do not have a default value are set to null.': '未被赋值的字段将被设置为默认值,没有默认值的设置为空值。',
|
||||
'Confirm': '确认',
|
||||
'Form value changed tip': '数据更新未保存,确定要退出吗?',
|
||||
'Dragging': '拖拽中',
|
||||
}
|
||||
|
@ -1,15 +1,17 @@
|
||||
import { css } from '@emotion/css';
|
||||
import { observer, RecursionField, useField, useFieldSchema } from '@formily/react';
|
||||
import { Drawer } from 'antd';
|
||||
import { Drawer, Modal as AntdModal } from 'antd';
|
||||
import classNames from 'classnames';
|
||||
import React from 'react';
|
||||
import { createPortal } from 'react-dom';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useActionContext } from './hooks';
|
||||
import { ComposedActionDrawer } from './types';
|
||||
|
||||
export const ActionDrawer: ComposedActionDrawer = observer((props) => {
|
||||
const { footerNodeName = 'Action.Drawer.Footer', ...others } = props;
|
||||
const { visible, setVisible } = useActionContext();
|
||||
const { t } = useTranslation();
|
||||
const { visible, setVisible, formValueChanged, setFormValueChanged } = useActionContext();
|
||||
const schema = useFieldSchema();
|
||||
const field = useField();
|
||||
const footerSchema = schema.reduceProperties((buf, s) => {
|
||||
@ -18,6 +20,21 @@ export const ActionDrawer: ComposedActionDrawer = observer((props) => {
|
||||
}
|
||||
return buf;
|
||||
});
|
||||
|
||||
const closeHandler = () => {
|
||||
if (!formValueChanged) {
|
||||
setVisible(false);
|
||||
return;
|
||||
}
|
||||
AntdModal.confirm({
|
||||
title: t('Confirm'),
|
||||
content: t('Form value changed tip'),
|
||||
async onOk() {
|
||||
setFormValueChanged(false);
|
||||
setVisible(false);
|
||||
},
|
||||
});
|
||||
};
|
||||
return (
|
||||
<>
|
||||
{createPortal(
|
||||
@ -32,7 +49,7 @@ export const ActionDrawer: ComposedActionDrawer = observer((props) => {
|
||||
{...others}
|
||||
destroyOnClose
|
||||
visible={visible}
|
||||
onClose={() => setVisible(false)}
|
||||
onClose={closeHandler}
|
||||
className={classNames(
|
||||
others.className,
|
||||
css`
|
||||
|
@ -80,6 +80,7 @@ export const Action: ComposedAction = observer((props: any) => {
|
||||
} = props;
|
||||
const { onClick } = useProps(props);
|
||||
const [visible, setVisible] = useState(false);
|
||||
const [formValueChanged, setFormValueChanged] = useState(false);
|
||||
const Designer = useDesigner();
|
||||
const field = useField<any>();
|
||||
const { run } = useAction();
|
||||
@ -117,7 +118,17 @@ export const Action: ComposedAction = observer((props: any) => {
|
||||
</SortableItem>
|
||||
);
|
||||
return (
|
||||
<ActionContext.Provider value={{ button: renderButton(), visible, setVisible, openMode, containerRefKey }}>
|
||||
<ActionContext.Provider
|
||||
value={{
|
||||
button: renderButton(),
|
||||
visible,
|
||||
setVisible,
|
||||
formValueChanged,
|
||||
setFormValueChanged,
|
||||
openMode,
|
||||
containerRefKey,
|
||||
}}
|
||||
>
|
||||
{popover && <RecursionField basePath={field.address} onlyRenderProperties schema={fieldSchema} />}
|
||||
{!popover && renderButton()}
|
||||
{!popover && props.children}
|
||||
|
@ -8,4 +8,6 @@ export interface ActionContextProps {
|
||||
setVisible?: (v: boolean) => void;
|
||||
openMode?: 'drawer' | 'modal' | 'page';
|
||||
containerRefKey?: string;
|
||||
formValueChanged?: boolean;
|
||||
setFormValueChanged?: (v: boolean) => void;
|
||||
}
|
||||
|
@ -1,8 +1,10 @@
|
||||
import { FormLayout } from '@formily/antd';
|
||||
import { createForm, Field } from '@formily/core';
|
||||
import { createForm, Field, onFormInputChange } from '@formily/core';
|
||||
import { FieldContext, FormContext, observer, RecursionField, useField, useFieldSchema } from '@formily/react';
|
||||
import { uid } from '@nocobase/utils';
|
||||
import { Spin } from 'antd';
|
||||
import React, { useMemo } from 'react';
|
||||
import React, { useEffect, useMemo } from 'react';
|
||||
import { useActionContext } from '..';
|
||||
import { useAttach, useComponent } from '../..';
|
||||
import { useProps } from '../../hooks/useProps';
|
||||
|
||||
@ -53,13 +55,37 @@ const FormDecorator: React.FC<FormProps> = (props) => {
|
||||
};
|
||||
|
||||
const WithForm = (props) => {
|
||||
const { form } = props;
|
||||
const fieldSchema = useFieldSchema();
|
||||
const { setFormValueChanged } = useActionContext();
|
||||
useEffect(() => {
|
||||
const id = uid();
|
||||
form.addEffects(id, () => {
|
||||
onFormInputChange((form) => {
|
||||
setFormValueChanged(true);
|
||||
});
|
||||
});
|
||||
return () => {
|
||||
form.removeEffects(id);
|
||||
};
|
||||
}, []);
|
||||
return fieldSchema['x-decorator'] === 'Form' ? <FormDecorator {...props} /> : <FormComponent {...props} />;
|
||||
};
|
||||
|
||||
const WithoutForm = (props) => {
|
||||
const fieldSchema = useFieldSchema();
|
||||
const form = useMemo(() => createForm(), []);
|
||||
const { setFormValueChanged } = useActionContext();
|
||||
const form = useMemo(
|
||||
() =>
|
||||
createForm({
|
||||
effects() {
|
||||
onFormInputChange((form) => {
|
||||
setFormValueChanged(true);
|
||||
});
|
||||
},
|
||||
}),
|
||||
[],
|
||||
);
|
||||
return fieldSchema['x-decorator'] === 'Form' ? (
|
||||
<FormDecorator form={form} {...props} />
|
||||
) : (
|
||||
|
Loading…
Reference in New Issue
Block a user