refactor: user alerts on destructive actions

This commit is contained in:
Carlos Valente
2024-04-27 10:04:36 +02:00
committed by Carlos Valente
parent dcbb92c470
commit 75b5118b0f
9 changed files with 73 additions and 19 deletions
@@ -20,6 +20,7 @@ export default function ShutdownPanel() {
const sendShutdown = () => { const sendShutdown = () => {
sendToElectron('shutdown', 'now'); sendToElectron('shutdown', 'now');
onClose();
}; };
return ( return (
@@ -30,10 +31,10 @@ export default function ShutdownPanel() {
This will shutdown the Ontime server. <br /> This will shutdown the Ontime server. <br />
The runtime state will be lost, but your project is kept for next time. The runtime state will be lost, but your project is kept for next time.
</Panel.Paragraph> </Panel.Paragraph>
<Button colorScheme='red' onClick={onOpen} isDisabled={!isElectron}> <Button colorScheme='red' onClick={onOpen} maxWidth='350px' isDisabled={!isElectron}>
Shutdown ontime Shutdown ontime
</Button> </Button>
<AlertDialog isOpen={isOpen} leastDestructiveRef={cancelRef} onClose={onClose}> <AlertDialog variant='ontime' isOpen={isOpen} leastDestructiveRef={cancelRef} onClose={onClose}>
<AlertDialogOverlay> <AlertDialogOverlay>
<AlertDialogContent> <AlertDialogContent>
<AlertDialogHeader fontSize='lg' fontWeight='bold'> <AlertDialogHeader fontSize='lg' fontWeight='bold'>
@@ -43,10 +44,10 @@ export default function ShutdownPanel() {
This will shutdown the Ontime server. <br /> Are you sure? This will shutdown the Ontime server. <br /> Are you sure?
</AlertDialogBody> </AlertDialogBody>
<AlertDialogFooter> <AlertDialogFooter>
<Button ref={cancelRef} onClick={onClose} variant='ghost'> <Button ref={cancelRef} onClick={onClose} variant='ontime-ghosted-white'>
Cancel Cancel
</Button> </Button>
<Button colorScheme='red' onClick={sendShutdown}> <Button colorScheme='red' onClick={sendShutdown} ml={4}>
Shutdown Shutdown
</Button> </Button>
</AlertDialogFooter> </AlertDialogFooter>
@@ -1,5 +1,14 @@
import { useCallback } from 'react'; import { useCallback, useRef } from 'react';
import { Button } from '@chakra-ui/react'; import {
AlertDialog,
AlertDialogBody,
AlertDialogContent,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogOverlay,
Button,
useDisclosure,
} from '@chakra-ui/react';
import { IoTrash } from '@react-icons/all-files/io5/IoTrash'; import { IoTrash } from '@react-icons/all-files/io5/IoTrash';
import { useEventAction } from '../../../common/hooks/useEventAction'; import { useEventAction } from '../../../common/hooks/useEventAction';
@@ -12,22 +21,48 @@ export default function RundownMenu() {
const appMode = useAppMode((state) => state.mode); const appMode = useAppMode((state) => state.mode);
const { deleteAllEvents } = useEventAction(); const { deleteAllEvents } = useEventAction();
const { isOpen, onOpen, onClose } = useDisclosure();
const cancelRef = useRef<HTMLButtonElement | null>(null);
const deleteAll = useCallback(() => { const deleteAll = useCallback(() => {
deleteAllEvents(); deleteAllEvents();
clearSelectedEvents(); clearSelectedEvents();
setCursor(null); setCursor(null);
}, [clearSelectedEvents, deleteAllEvents, setCursor]); onClose();
}, [clearSelectedEvents, deleteAllEvents, onClose, setCursor]);
return ( return (
<Button <>
size='sm' <Button
variant='ontime-outlined' size='sm'
leftIcon={<IoTrash />} variant='ontime-outlined'
onClick={deleteAll} leftIcon={<IoTrash />}
color='#FA5656' onClick={onOpen}
isDisabled={appMode === 'run'} color='#FA5656'
> isDisabled={appMode === 'run'}
Clear rundown >
</Button> Clear rundown
</Button>
<AlertDialog variant='ontime' isOpen={isOpen} leastDestructiveRef={cancelRef} onClose={onClose}>
<AlertDialogOverlay>
<AlertDialogContent>
<AlertDialogHeader fontSize='lg' fontWeight='bold'>
Clear rundown
</AlertDialogHeader>
<AlertDialogBody>
You will lose all data in your rundown. <br /> Are you sure?
</AlertDialogBody>
<AlertDialogFooter>
<Button ref={cancelRef} onClick={onClose} variant='ontime-ghosted-white'>
Cancel
</Button>
<Button colorScheme='red' onClick={deleteAll} ml={4}>
Delete all
</Button>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialogOverlay>
</AlertDialog>
</>
); );
} }
+8
View File
@@ -10,3 +10,11 @@ export const ontimeAlertOnDark = {
color: '#578AF4', // $blue-500 color: '#578AF4', // $blue-500
}, },
}; };
export const ontimeDialog = {
container: {
backgroundColor: '#1a1a1a', // $gray-1300
color: '#e2e2e2', // $gray-200
borderRadius: '3px',
},
};
+6 -1
View File
@@ -1,6 +1,6 @@
import { extendTheme } from '@chakra-ui/react'; import { extendTheme } from '@chakra-ui/react';
import { ontimeAlertOnDark } from './OntimeAlert'; import { ontimeAlertOnDark, ontimeDialog } from './OntimeAlert';
import { import {
ontimeButtonFilled, ontimeButtonFilled,
ontimeButtonGhosted, ontimeButtonGhosted,
@@ -35,6 +35,11 @@ const theme = extendTheme({
'ontime-on-dark-info': { ...ontimeAlertOnDark }, 'ontime-on-dark-info': { ...ontimeAlertOnDark },
}, },
}, },
AlertDialog: {
variants: {
ontime: { ...ontimeDialog },
},
},
Button: { Button: {
baseStyle: { baseStyle: {
letterSpacing: '0.3px', letterSpacing: '0.3px',
+1
View File
@@ -6,6 +6,7 @@ test('project file upload', async ({ page }) => {
await page.goto('http://localhost:4001/editor'); await page.goto('http://localhost:4001/editor');
await page.getByRole('button', { name: 'Edit' }).click(); await page.getByRole('button', { name: 'Edit' }).click();
await page.getByRole('button', { name: 'Clear rundown' }).click(); await page.getByRole('button', { name: 'Clear rundown' }).click();
await page.getByRole('button', { name: 'Delete all' }).click();
await page.getByRole('button', { name: 'toggle settings' }).click(); await page.getByRole('button', { name: 'toggle settings' }).click();
await page.getByRole('button', { name: 'Project', exact: true }).click(); await page.getByRole('button', { name: 'Project', exact: true }).click();
@@ -6,6 +6,7 @@ test('delay blocks add time to events', async ({ page }) => {
// delete all events and add a new one // delete all events and add a new one
await page.getByRole('button', { name: 'Edit' }).click(); await page.getByRole('button', { name: 'Edit' }).click();
await page.getByRole('button', { name: 'Clear rundown' }).click(); await page.getByRole('button', { name: 'Clear rundown' }).click();
await page.getByRole('button', { name: 'Delete all' }).click();
await page.getByRole('button', { name: 'Create event' }).click(); await page.getByRole('button', { name: 'Create event' }).click();
// add data to new event // add data to new event
@@ -53,6 +54,7 @@ test('delays are show correctly', async ({ page }) => {
// add a test event // add a test event
await page.getByRole('button', { name: 'Edit' }).click(); await page.getByRole('button', { name: 'Edit' }).click();
await page.getByRole('button', { name: 'Clear rundown' }).click(); await page.getByRole('button', { name: 'Clear rundown' }).click();
await page.getByRole('button', { name: 'Delete all' }).click();
await page.getByRole('button', { name: 'Create Event' }).click(); await page.getByRole('button', { name: 'Create Event' }).click();
await page.getByTestId('time-input-timeStart').click(); await page.getByTestId('time-input-timeStart').click();
+1 -1
View File
@@ -3,9 +3,9 @@ import { test, expect } from '@playwright/test';
test('CRUD operations on the rundown', async ({ page }) => { test('CRUD operations on the rundown', async ({ page }) => {
await page.goto('http://localhost:4001/editor'); await page.goto('http://localhost:4001/editor');
// clear rundown
await page.getByRole('button', { name: 'Edit' }).click(); await page.getByRole('button', { name: 'Edit' }).click();
await page.getByRole('button', { name: 'Clear rundown' }).click(); await page.getByRole('button', { name: 'Clear rundown' }).click();
await page.getByRole('button', { name: 'Delete all' }).click();
// create event from the rundown empty button // create event from the rundown empty button
await page.getByRole('button', { name: 'Create Event' }).click(); await page.getByRole('button', { name: 'Create Event' }).click();
+1
View File
@@ -5,6 +5,7 @@ test('smoke test operator', async ({ page }) => {
await page.goto('http://localhost:4001/editor'); await page.goto('http://localhost:4001/editor');
await page.getByRole('button', { name: 'Edit' }).click(); await page.getByRole('button', { name: 'Edit' }).click();
await page.getByRole('button', { name: 'Clear rundown' }).click(); await page.getByRole('button', { name: 'Clear rundown' }).click();
await page.getByRole('button', { name: 'Delete all' }).click();
await page.getByRole('button', { name: 'Create Event' }).click(); await page.getByRole('button', { name: 'Create Event' }).click();
await page.getByTestId('time-input-timeStart').fill('1m'); await page.getByTestId('time-input-timeStart').fill('1m');
@@ -6,6 +6,7 @@ test('sheet file upload', async ({ page }) => {
await page.goto('http://localhost:4001/editor'); await page.goto('http://localhost:4001/editor');
await page.getByRole('button', { name: 'Edit' }).click(); await page.getByRole('button', { name: 'Edit' }).click();
await page.getByRole('button', { name: 'Clear rundown' }).click(); await page.getByRole('button', { name: 'Clear rundown' }).click();
await page.getByRole('button', { name: 'Delete all' }).click();
await page.getByRole('button', { name: 'Toggle settings' }).click(); await page.getByRole('button', { name: 'Toggle settings' }).click();
await page.getByRole('button', { name: 'Import spreadsheet' }).click(); await page.getByRole('button', { name: 'Import spreadsheet' }).click();