import * as React from 'react';
import PropTypes from 'prop-types';
import Button from '@mui/material/Button';
import Dialog from '@mui/material/Dialog';
import DialogActions from '@mui/material/DialogActions';
import DialogContent from '@mui/material/DialogContent';
import DialogContentText from '@mui/material/DialogContentText';
import DialogTitle from '@mui/material/DialogTitle';
import TextField from '@mui/material/TextField';
import useEventCallback from '@mui/utils/useEventCallback';
import DialogsContext from './DialogsContext';
/**
* The props that are passed to a dialog component.
*/
function useDialogLoadingButton(onClose) {
const [loading, setLoading] = React.useState(false);
const handleClick = async () => {
try {
setLoading(true);
await onClose();
} finally {
setLoading(false);
}
};
return {
onClick: handleClick,
loading,
};
}
function AlertDialog({ open, payload, onClose }) {
const okButtonProps = useDialogLoadingButton(() => onClose());
return (
);
}
AlertDialog.propTypes = {
/**
* A function to call when the dialog should be closed. If the dialog has a return
* value, it should be passed as an argument to this function. You should use the promise
* that is returned to show a loading state while the dialog is performing async actions
* on close.
* @param result The result to return from the dialog.
* @returns A promise that resolves when the dialog can be fully closed.
*/
onClose: PropTypes.func.isRequired,
/**
* Whether the dialog is open.
*/
open: PropTypes.bool.isRequired,
/**
* The payload that was passed when the dialog was opened.
*/
payload: PropTypes.shape({
msg: PropTypes.node,
okText: PropTypes.node,
onClose: PropTypes.func,
title: PropTypes.node,
}).isRequired,
};
export { AlertDialog };
function ConfirmDialog({ open, payload, onClose }) {
const cancelButtonProps = useDialogLoadingButton(() => onClose(false));
const okButtonProps = useDialogLoadingButton(() => onClose(true));
return (
);
}
ConfirmDialog.propTypes = {
/**
* A function to call when the dialog should be closed. If the dialog has a return
* value, it should be passed as an argument to this function. You should use the promise
* that is returned to show a loading state while the dialog is performing async actions
* on close.
* @param result The result to return from the dialog.
* @returns A promise that resolves when the dialog can be fully closed.
*/
onClose: PropTypes.func.isRequired,
/**
* Whether the dialog is open.
*/
open: PropTypes.bool.isRequired,
/**
* The payload that was passed when the dialog was opened.
*/
payload: PropTypes.shape({
cancelText: PropTypes.node,
msg: PropTypes.node,
okText: PropTypes.node,
onClose: PropTypes.func,
severity: PropTypes.oneOf(['error', 'info', 'success', 'warning']),
title: PropTypes.node,
}).isRequired,
};
export { ConfirmDialog };
function PromptDialog({ open, payload, onClose }) {
const [input, setInput] = React.useState('');
const cancelButtonProps = useDialogLoadingButton(() => onClose(null));
const [loading, setLoading] = React.useState(false);
const name = 'input';
return (
);
}
PromptDialog.propTypes = {
/**
* A function to call when the dialog should be closed. If the dialog has a return
* value, it should be passed as an argument to this function. You should use the promise
* that is returned to show a loading state while the dialog is performing async actions
* on close.
* @param result The result to return from the dialog.
* @returns A promise that resolves when the dialog can be fully closed.
*/
onClose: PropTypes.func.isRequired,
/**
* Whether the dialog is open.
*/
open: PropTypes.bool.isRequired,
/**
* The payload that was passed when the dialog was opened.
*/
payload: PropTypes.shape({
cancelText: PropTypes.node,
msg: PropTypes.node,
okText: PropTypes.node,
onClose: PropTypes.func,
title: PropTypes.node,
}).isRequired,
};
export { PromptDialog };
export function useDialogs() {
const dialogsContext = React.useContext(DialogsContext);
if (!dialogsContext) {
throw new Error('Dialogs context was used without a provider.');
}
const { open, close } = dialogsContext;
const alert = useEventCallback((msg, { onClose, ...options } = {}) =>
open(AlertDialog, { ...options, msg }, { onClose }),
);
const confirm = useEventCallback((msg, { onClose, ...options } = {}) =>
open(ConfirmDialog, { ...options, msg }, { onClose }),
);
const prompt = useEventCallback((msg, { onClose, ...options } = {}) =>
open(PromptDialog, { ...options, msg }, { onClose }),
);
return React.useMemo(
() => ({
alert,
confirm,
prompt,
open,
close,
}),
[alert, close, confirm, open, prompt],
);
}