Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[docs][toolpad] Remove extra code block #44120

Open
wants to merge 16 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 67 additions & 59 deletions docs/data/material/components/dialogs/ToolpadDialogsNoSnap.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,59 @@ import Alert from '@mui/material/Alert';
import DialogTitle from '@mui/material/DialogTitle';
import DialogContent from '@mui/material/DialogContent';
import DialogActions from '@mui/material/DialogActions';
import TextField from '@mui/material/TextField';
import Typography from '@mui/material/Typography';

function DeleteDialog({ open, onClose, payload }) {
const [inputValue, setInputValue] = React.useState('');
const isInputValid = inputValue === payload;

const handleKeyDown = (event) => {
if (event.key === 'Enter' && isInputValid) {
onClose(inputValue);
}
};

function MyCustomDialog({ open, onClose, payload }) {
return (
<Dialog fullWidth open={open} onClose={() => onClose()}>
<DialogTitle>Custom Error Handler</DialogTitle>
<Dialog fullWidth maxWidth="sm" open={open} onClose={() => onClose('')}>
<DialogTitle>Are you sure you want to delete this project?</DialogTitle>
<DialogContent>
<Typography variant="body1" gutterBottom>
This action cannot be undone. This will permanently delete the project, its
data, and remove all collaborator associations.
</Typography>
<Alert severity="error">
{`An error occurred while deleting item "${payload.id}":`}
<pre>{payload.error}</pre>
Please type{' '}
<strong>
<code>{payload}</code>
</strong>{' '}
to confirm.
</Alert>
<TextField
fullWidth
value={inputValue}
onChange={(event) => setInputValue(event.target.value)}
onKeyDown={handleKeyDown}
margin="normal"
variant="outlined"
size="small"
/>
</DialogContent>
<DialogActions>
<Button onClick={() => onClose()}>Close me</Button>
<Button onClick={() => onClose('')}>Cancel</Button>
<Button
color="error"
disabled={!isInputValid}
onClick={() => onClose(inputValue)}
>
I understand, delete this project
</Button>
</DialogActions>
</Dialog>
);
}

MyCustomDialog.propTypes = {
DeleteDialog.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
Expand All @@ -43,78 +77,52 @@ MyCustomDialog.propTypes = {
/**
* The payload that was passed when the dialog was opened.
*/
payload: PropTypes.shape({
error: PropTypes.string,
id: PropTypes.string,
}).isRequired,
payload: PropTypes.string.isRequired,
};

const mockApiDelete = async (id) => {
return new Promise((resolve, reject) => {
const mockApiDelete = async () => {
return new Promise((resolve) => {
setTimeout(() => {
if (!id) {
reject(new Error('ID is required'));
} else if (parseInt(id, 10) % 2 === 0) {
console.log('id', parseInt(id, 10));
resolve(true);
} else if (parseInt(id, 10) % 2 === 1) {
reject(new Error('Can not delete odd numbered elements'));
} else if (Number.isNaN(parseInt(id, 10))) {
reject(new Error('ID must be a number'));
} else {
reject(new Error('Unknown error'));
}
resolve(1);
}, 1000);
});
};

function DemoContent() {
function DeleteDialogTrigger({ name }) {
const dialogs = useDialogs();
const [isDeleting, setIsDeleting] = React.useState(false);

const handleDelete = async () => {
const id = await dialogs.prompt('Enter the ID to delete', {
okText: 'Delete',
cancelText: 'Cancel',
});

if (id) {
const deleteConfirmed = await dialogs.confirm(
`Are you sure you want to delete "${id}"?`,
);
if (deleteConfirmed) {
try {
setIsDeleting(true);
await mockApiDelete(id);
dialogs.alert('Deleted!');
} catch (error) {
const message = error instanceof Error ? error.message : 'Unknown error';
await dialogs.open(MyCustomDialog, { id, error: message });
} finally {
setIsDeleting(false);
}
const response = await dialogs.open(DeleteDialog, name);
if (response === name) {
try {
setIsDeleting(true);
await mockApiDelete();
dialogs.alert(
<React.Fragment>
Deleted project <code>{name}</code>.
</React.Fragment>,
);
} finally {
setIsDeleting(false);
}
}
};

return (
<div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
<div style={{ display: 'flex', gap: 16 }}>
<LoadingButton
variant="contained"
loading={isDeleting}
onClick={handleDelete}
>
Delete
</LoadingButton>
</div>
</div>
<LoadingButton loading={isDeleting} variant="contained" onClick={handleDelete}>
Delete
</LoadingButton>
);
}

DeleteDialogTrigger.propTypes = {
name: PropTypes.string.isRequired,
};

export default function ToolpadDialogsNoSnap() {
return (
<DialogsProvider>
<DemoContent />
<DeleteDialogTrigger name="demo" />
</DialogsProvider>
);
}
118 changes: 60 additions & 58 deletions docs/data/material/components/dialogs/ToolpadDialogsNoSnap.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,95 +7,97 @@ import Alert from '@mui/material/Alert';
import DialogTitle from '@mui/material/DialogTitle';
import DialogContent from '@mui/material/DialogContent';
import DialogActions from '@mui/material/DialogActions';
import TextField from '@mui/material/TextField';
import Typography from '@mui/material/Typography';

interface DeleteError {
id: string | null;
error: string | null;
}
function DeleteDialog({ open, onClose, payload }: DialogProps<string, string>) {
const [inputValue, setInputValue] = React.useState('');
const isInputValid = inputValue === payload;

const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
if (event.key === 'Enter' && isInputValid) {
onClose(inputValue);
}
};

function MyCustomDialog({ open, onClose, payload }: DialogProps<DeleteError>) {
return (
<Dialog fullWidth open={open} onClose={() => onClose()}>
<DialogTitle>Custom Error Handler</DialogTitle>
<Dialog fullWidth maxWidth="sm" open={open} onClose={() => onClose('')}>
<DialogTitle>Are you sure you want to delete this project?</DialogTitle>
<DialogContent>
<Typography variant="body1" gutterBottom>
This action cannot be undone. This will permanently delete the project, its
data, and remove all collaborator associations.
</Typography>
<Alert severity="error">
{`An error occurred while deleting item "${payload.id}":`}
<pre>{payload.error}</pre>
Please type{' '}
<strong>
<code>{payload}</code>
</strong>{' '}
to confirm.
</Alert>
<TextField
fullWidth
value={inputValue}
onChange={(event) => setInputValue(event.target.value)}
onKeyDown={handleKeyDown}
margin="normal"
variant="outlined"
size="small"
/>
</DialogContent>
<DialogActions>
<Button onClick={() => onClose()}>Close me</Button>
<Button onClick={() => onClose('')}>Cancel</Button>
<Button
color="error"
disabled={!isInputValid}
onClick={() => onClose(inputValue)}
>
I understand, delete this project
</Button>
</DialogActions>
</Dialog>
);
}

const mockApiDelete = async (id: string | null) => {
return new Promise((resolve, reject) => {
const mockApiDelete = async () => {
return new Promise((resolve) => {
setTimeout(() => {
if (!id) {
reject(new Error('ID is required'));
} else if (parseInt(id, 10) % 2 === 0) {
console.log('id', parseInt(id, 10));
resolve(true);
} else if (parseInt(id, 10) % 2 === 1) {
reject(new Error('Can not delete odd numbered elements'));
} else if (Number.isNaN(parseInt(id, 10))) {
reject(new Error('ID must be a number'));
} else {
reject(new Error('Unknown error'));
}
resolve(1);
}, 1000);
});
};

function DemoContent() {
function DeleteDialogTrigger({ name }: { name: string }) {
const dialogs = useDialogs();
const [isDeleting, setIsDeleting] = React.useState(false);

const handleDelete = async () => {
const id = await dialogs.prompt('Enter the ID to delete', {
okText: 'Delete',
cancelText: 'Cancel',
});

if (id) {
const deleteConfirmed = await dialogs.confirm(
`Are you sure you want to delete "${id}"?`,
);
if (deleteConfirmed) {
try {
setIsDeleting(true);
await mockApiDelete(id);
dialogs.alert('Deleted!');
} catch (error) {
const message = error instanceof Error ? error.message : 'Unknown error';
await dialogs.open(MyCustomDialog, { id, error: message });
} finally {
setIsDeleting(false);
}
const response = await dialogs.open(DeleteDialog, name);
if (response === name) {
try {
setIsDeleting(true);
await mockApiDelete();
dialogs.alert(
<React.Fragment>
Deleted project <code>{name}</code>.
</React.Fragment>,
);
} finally {
setIsDeleting(false);
}
}
};

return (
<div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
<div style={{ display: 'flex', gap: 16 }}>
<LoadingButton
variant="contained"
loading={isDeleting}
onClick={handleDelete}
>
Delete
</LoadingButton>
</div>
</div>
<LoadingButton loading={isDeleting} variant="contained" onClick={handleDelete}>
Delete
</LoadingButton>
);
}

export default function ToolpadDialogsNoSnap() {
return (
<DialogsProvider>
<DemoContent />
<DeleteDialogTrigger name="demo" />
</DialogsProvider>
);
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
<DialogsProvider>
<DemoContent />
<DeleteDialogTrigger name="demo" />
</DialogsProvider>
Loading
Loading