import React, { FC, useEffect } from 'react'; import { Prompt, useHistory } from 'react-router'; import { Box, FlexProps, Flex } from '@chakra-ui/react'; import Modal from '../modal'; import Space from '../space'; import { ConfigContext } from '../config-provider'; import defaultLocale from '../locale/en_US'; import useContextualSaveBarState from './useContextualSaveBarState'; import Button, { ButtonProps } from '../button'; interface confirmModalType { /** 取消的二次确认标题 */ title?: string; /** 取消的二次确认内容 */ content?: string; /** 取消的二次确认的 ok 按钮文字 */ okText?: string; /** 取消的二次确认的 cancel 按钮文字 */ cancelText?: string; /** 取消的二次确认的 ok 按钮 props */ okButtonProps?: ButtonProps; /** 取消的二次确认的 cancel 按钮 props */ cancelButtonProps?: ButtonProps; } export interface ContextualSaveBarProps extends FlexProps { /** 左上角区域 */ logo?: React.ReactNode; /** 保存条中间显示的文字 */ title?: string; /** 保存按钮文字 */ okText?: string; /** 保存按钮属性 */ okButtonProps?: ButtonProps; /** 取消按钮属性 */ cancelButtonProps?: ButtonProps; /** 取消按钮文字 */ cancelText?: string; /** 取消保存的二次确认 Modal 的属性 */ cancelConfirmModal?: confirmModalType; /** 离开页面的二次确认 Modal 的属性 */ leaveConfirmModal?: confirmModalType; /** 保存回调 */ onOK?: () => void; /** 取消回调 */ onCancel?: () => void; /** 当 visible 为 true 时,离开页面的回调,参数 path 为要跳转的路由 */ onLeave?: (path: string) => void; } const ContextualSaveBar: FC = ({ logo, title, okText, okButtonProps, cancelText, cancelButtonProps, cancelConfirmModal, leaveConfirmModal, onOK, onCancel, onLeave, ...rest }) => { const { locale: { ContextualSaveBar: locale } = { ContextualSaveBar: defaultLocale.ContextualSaveBar }, logo: globalLogo, } = React.useContext(ConfigContext); const history = useHistory(); const [visible, setVisible] = useContextualSaveBarState(); useEffect(() => { const listener = (e: BeforeUnloadEvent) => { e.preventDefault(); e.returnValue = leaveConfirmModal?.content || locale?.leavePageMessage; }; if (visible) { window.addEventListener('beforeunload', listener); } return () => { window.removeEventListener('beforeunload', listener); }; }, [leaveConfirmModal?.content, locale?.leavePageMessage, visible]); const handleLeaveConfirm = (pathname: string) => Modal.confirm({ title: leaveConfirmModal?.title || locale?.title, content: leaveConfirmModal?.content || locale?.leavePageMessage, okText: leaveConfirmModal?.okText || locale?.leavePageText, okButtonProps: { danger: true, ...leaveConfirmModal?.okButtonProps, }, cancelButtonProps: leaveConfirmModal?.cancelButtonProps, onOk: () => { setVisible(false); setTimeout(() => { if (onLeave) { onLeave(pathname); } else { history.push(pathname); } }); }, }); const handleCancelConfirm = () => Modal.confirm({ title: cancelConfirmModal?.title || locale?.title, content: cancelConfirmModal?.content || locale?.message, okText: cancelConfirmModal?.okText || locale?.primaryAction, cancelText: cancelConfirmModal?.cancelText || locale?.secondaryAction, okButtonProps: { danger: true, ...cancelConfirmModal?.okButtonProps, }, cancelButtonProps: cancelConfirmModal?.cancelButtonProps, onOk: () => { setVisible(false); if (onCancel) { setTimeout(onCancel); } }, }); return visible ? ( {logo || globalLogo} {title || locale?.unsavedChanges} { if (Object.keys(query).length > 0) { handleLeaveConfirm(`${pathname}?${new URLSearchParams(query).toString()}`); } else { handleLeaveConfirm(pathname); } return false; }} /> ) : null; }; export default ContextualSaveBar;