mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-09 09:23:51 +00:00
Merge branch 'master' into feat/info
This commit is contained in:
@@ -7,6 +7,10 @@ body,
|
||||
html,
|
||||
.App {
|
||||
margin: 0px auto;
|
||||
overflow: hidden;
|
||||
overflow: clip;
|
||||
height: 100vh;
|
||||
-webkit-user-select: none;
|
||||
user-select: none;
|
||||
-webkit-app-region: drag;
|
||||
}
|
||||
|
||||
@@ -37,7 +37,6 @@ export const downloadEvents = async () => {
|
||||
};
|
||||
|
||||
export const uploadEvents = async (file) => {
|
||||
console.log('uploading', file);
|
||||
const formData = new FormData();
|
||||
formData.append('jsondb', file); // appending file
|
||||
await axios
|
||||
@@ -49,3 +48,7 @@ export const uploadEvents = async (file) => {
|
||||
.then((res) => console.log(res.data))
|
||||
.catch((err) => console.error(err));
|
||||
};
|
||||
|
||||
export const uploadEventsWithPath = async (filepath) => {
|
||||
await axios.post(ontimeURL + '/dbpath', { path: filepath });
|
||||
};
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
import { IconButton } from '@chakra-ui/button';
|
||||
import { Tooltip } from '@chakra-ui/tooltip';
|
||||
import { FiChevronsDown } from 'react-icons/fi';
|
||||
|
||||
export default function ApplyIconBtn(props) {
|
||||
const { clickhandler, ...rest } = props;
|
||||
return (
|
||||
<IconButton
|
||||
size={props.size || 'xs'}
|
||||
icon={<FiChevronsDown />}
|
||||
colorScheme='orange'
|
||||
onClick={clickhandler}
|
||||
_focus={{ boxShadow: 'none' }}
|
||||
{...rest}
|
||||
/>
|
||||
<Tooltip label='Apply delays'>
|
||||
<IconButton
|
||||
size={props.size || 'xs'}
|
||||
icon={<FiChevronsDown />}
|
||||
colorScheme='orange'
|
||||
onClick={clickhandler}
|
||||
_focus={{ boxShadow: 'none' }}
|
||||
{...rest}
|
||||
/>
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6,13 +6,13 @@ export default function LockIconBtn(props) {
|
||||
const { clickhandler, active, ref } = props;
|
||||
return (
|
||||
<Tooltip label='Lock cursor to current'>
|
||||
<IconButton
|
||||
<IconButton
|
||||
ref={ref}
|
||||
size={props.size || 'xs'}
|
||||
icon={<FiTarget />}
|
||||
color={active ? 'pink.100' : 'pink.300'}
|
||||
borderColor={active ? undefined : 'pink.300'}
|
||||
backgroundColor={active ? 'pink.300' : undefined}
|
||||
backgroundColor={active ? 'pink.400' : undefined}
|
||||
variant={active ? 'solid' : 'outline'}
|
||||
onClick={clickhandler}
|
||||
_focus={{ boxShadow: 'none' }}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
import { IconButton } from '@chakra-ui/button';
|
||||
import { Tooltip } from '@chakra-ui/tooltip';
|
||||
import { FiUsers } from 'react-icons/fi';
|
||||
|
||||
export default function PublicIconBtn(props) {
|
||||
const { actionHandler, active, ...rest } = props;
|
||||
return (
|
||||
<Tooltip label={active ? 'Make event private' : 'Make event public'}>
|
||||
<IconButton
|
||||
size={props.size || 'xs'}
|
||||
icon={<FiUsers />}
|
||||
colorScheme='blue'
|
||||
variant={active ? 'solid' : 'outline'}
|
||||
onClick={() =>
|
||||
actionHandler('update', { field: 'isPublic', value: !active })
|
||||
}
|
||||
_focus={{ boxShadow: 'none' }}
|
||||
{...rest}
|
||||
/>
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
import { Flex, Text } from '@chakra-ui/layout';
|
||||
import styles from './NumberedText.module.css';
|
||||
|
||||
export default function NumberedText({ number = 1, text = '' }) {
|
||||
return (
|
||||
<Flex>
|
||||
<div className={styles.stylednumber}>{number}</div>
|
||||
<Text>{text}</Text>
|
||||
</Flex>
|
||||
);
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
.stylednumber {
|
||||
display: inline;
|
||||
text-align: center;
|
||||
color: white;
|
||||
font-weight: 600;
|
||||
|
||||
background-color: #ff5b7e;
|
||||
border: 1px solid rgba(255,255,255,0.17);
|
||||
width: 1.5em;
|
||||
border-radius: 1em;
|
||||
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
@@ -8,9 +8,12 @@
|
||||
|
||||
.block {
|
||||
display: 'block';
|
||||
overflow-x: hidden;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.inline {
|
||||
display: inline;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
import { lazy, useEffect } from 'react';
|
||||
import { Heading } from '@chakra-ui/layout';
|
||||
import { Box } from '@chakra-ui/layout';
|
||||
@@ -28,50 +29,33 @@ export default function Editor() {
|
||||
|
||||
<div className={styles.mainContainer}>
|
||||
<Box id='settings' className={styles.settings}>
|
||||
<MenuBar onOpen={onOpen} onClose={onClose} />
|
||||
<MenuBar onOpen={onOpen} />
|
||||
</Box>
|
||||
|
||||
<Box className={styles.editor}>
|
||||
<Heading size='lg' paddingBottom={'0.25em'}>
|
||||
Event List
|
||||
</Heading>
|
||||
<NumberedText number={1} text={'Manage events'} />
|
||||
<h1>Event List</h1>
|
||||
<div className={styles.content}>
|
||||
<EventListWrapper />
|
||||
</div>
|
||||
</Box>
|
||||
|
||||
<Box className={styles.messages}>
|
||||
<Heading size='lg' paddingBottom={'0.25em'}>
|
||||
Display Messages
|
||||
</Heading>
|
||||
<NumberedText
|
||||
number={3}
|
||||
text={'Show realtime messages on different screens'}
|
||||
/>
|
||||
<h1>Display Messages</h1>
|
||||
<div className={styles.content}>
|
||||
<MessageControl />
|
||||
</div>
|
||||
</Box>
|
||||
|
||||
<Box className={styles.playback}>
|
||||
<Heading size='lg' paddingBottom={'0.25em'}>
|
||||
Time Control
|
||||
</Heading>
|
||||
<NumberedText number={2} text={'Control timers'} />
|
||||
<h1>Timer Control</h1>
|
||||
<div className={styles.content}>
|
||||
<PlaybackControl />
|
||||
</div>
|
||||
</Box>
|
||||
|
||||
<Box className={styles.info} borderRadius='0.5em' overflowX='auto'>
|
||||
<Heading size='lg' paddingBottom={'0.25em'}>
|
||||
Info
|
||||
</Heading>
|
||||
<NumberedText number={4} text={'Running Info'} />
|
||||
<div className={styles.content}>
|
||||
<Info />
|
||||
</div>
|
||||
<h1>Info</h1>
|
||||
<div className={styles.content}></div>
|
||||
</Box>
|
||||
</div>
|
||||
</>
|
||||
|
||||
@@ -69,6 +69,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2.5vh;
|
||||
color: rgba(255, 255, 255, 0.63);
|
||||
padding-bottom: 0.25em;
|
||||
}
|
||||
|
||||
.mainContainer > div {
|
||||
border-radius: 0.5em;
|
||||
height: 100%;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Menu, MenuButton, MenuItem, MenuList } from '@chakra-ui/menu';
|
||||
import { IconButton } from '@chakra-ui/button';
|
||||
import { FiZap, FiPlus, FiMinusCircle, FiClock } from 'react-icons/fi';
|
||||
import { FiPlus, FiMinusCircle, FiClock } from 'react-icons/fi';
|
||||
|
||||
export default function ActionButtons(props) {
|
||||
const { showAdd, showDelay, showBlock, actionHandler } = props;
|
||||
@@ -16,7 +16,7 @@ export default function ActionButtons(props) {
|
||||
as={IconButton}
|
||||
aria-label='Options'
|
||||
size='xs'
|
||||
icon={<FiZap />}
|
||||
icon={<FiPlus />}
|
||||
_expanded={{ bg: 'orange.300', color: 'white' }}
|
||||
_focus={{ boxShadow: 'none' }}
|
||||
backgroundColor={'orange.200'}
|
||||
|
||||
@@ -6,7 +6,7 @@ import EventTimes from 'common/components/eventTimes/EventTimes';
|
||||
import EventTimesVertical from 'common/components/eventTimes/EventTimesVertical';
|
||||
import EditableText from 'common/input/EditableText';
|
||||
import ActionButtons from './ActionButtons';
|
||||
import VisibleIconBtn from 'common/components/buttons/VisibleIconBtn';
|
||||
import PublicIconBtn from 'common/components/buttons/PublicIconBtn';
|
||||
import DeleteIconBtn from 'common/components/buttons/DeleteIconBtn';
|
||||
import { millisToMinutes } from 'common/dateConfig';
|
||||
import style from './EventBlock.module.css';
|
||||
@@ -94,7 +94,7 @@ const ExpandedBlock = (props) => {
|
||||
onClick={() => props.setCollapsed(true)}
|
||||
/>
|
||||
<div className={style.actionOverlay}>
|
||||
<VisibleIconBtn actionHandler={actionHandler} active={data.isPublic} />
|
||||
<PublicIconBtn actionHandler={actionHandler} active={data.isPublic} />
|
||||
<ActionButtons
|
||||
showAdd
|
||||
showDelay
|
||||
@@ -147,7 +147,7 @@ const CollapsedBlock = (props) => {
|
||||
onClick={() => props.setCollapsed(false)}
|
||||
/>
|
||||
<div className={style.actionOverlay}>
|
||||
<VisibleIconBtn actionHandler={actionHandler} active={data.isPublic} />
|
||||
<PublicIconBtn actionHandler={actionHandler} active={data.isPublic} />
|
||||
<ActionButtons
|
||||
showAdd
|
||||
showDelay
|
||||
|
||||
@@ -152,6 +152,8 @@
|
||||
font-size: 0.8em;
|
||||
float: right;
|
||||
padding-right: 1em;
|
||||
-webkit-user-select: text;
|
||||
user-select: text;
|
||||
}
|
||||
|
||||
/* ================ MORE ================ */
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
import { Menu, MenuButton, MenuItem, MenuList } from '@chakra-ui/menu';
|
||||
import { IconButton } from '@chakra-ui/button';
|
||||
import {
|
||||
FiTrash2,
|
||||
FiZap,
|
||||
FiPlus,
|
||||
FiClock,
|
||||
FiMinusCircle,
|
||||
} from 'react-icons/fi';
|
||||
import { FiTrash2, FiPlus, FiClock, FiMinusCircle } from 'react-icons/fi';
|
||||
import { Divider } from '@chakra-ui/layout';
|
||||
|
||||
export default function MenuActionButtons(props) {
|
||||
@@ -20,9 +14,9 @@ export default function MenuActionButtons(props) {
|
||||
<Menu isLazy lazyBehavior='unmount'>
|
||||
<MenuButton
|
||||
as={IconButton}
|
||||
aria-label='Options'
|
||||
aria-label='Create Menu'
|
||||
size={props.size || 'xs'}
|
||||
icon={<FiZap />}
|
||||
icon={<FiPlus />}
|
||||
_expanded={{ bg: 'orange.300', color: 'white' }}
|
||||
_focus={{ boxShadow: 'none' }}
|
||||
backgroundColor={'orange.200'}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import { downloadEvents } from 'app/api/ontimeApi';
|
||||
import { useMutation, useQueryClient } from 'react-query';
|
||||
import { downloadEvents, uploadEvents } from 'app/api/ontimeApi';
|
||||
import { EVENTS_TABLE } from 'app/api/apiConstants';
|
||||
import DownloadIconBtn from './buttons/DownloadIconBtn';
|
||||
import SettingsIconBtn from './buttons/SettingsIconBtn';
|
||||
import InfoIconBtn from './buttons/InfoIconBtn';
|
||||
@@ -7,24 +9,105 @@ import MinIconBtn from './buttons/MinIconBtn';
|
||||
import QuitIconBtn from './buttons/QuitIconBtn';
|
||||
import style from './MenuBar.module.css';
|
||||
import HelpIconBtn from './buttons/HelpIconBtn';
|
||||
import UploadIconBtn from './buttons/UploadIconBtn';
|
||||
import { useRef } from 'react';
|
||||
|
||||
const { ipcRenderer } = window.require('electron');
|
||||
|
||||
export default function MenuBar(props) {
|
||||
const { onOpen, onClose } = props;
|
||||
const { onOpen } = props;
|
||||
const hiddenFileInput = useRef(null);
|
||||
const queryClient = useQueryClient();
|
||||
const uploaddb = useMutation(uploadEvents, {
|
||||
onSettled: () => {
|
||||
queryClient.invalidateQueries(EVENTS_TABLE);
|
||||
},
|
||||
});
|
||||
|
||||
const handleDownload = () => {
|
||||
downloadEvents();
|
||||
};
|
||||
|
||||
const handleClick = () => {
|
||||
if (hiddenFileInput && hiddenFileInput.current) {
|
||||
hiddenFileInput.current.click();
|
||||
}
|
||||
};
|
||||
|
||||
const handleUpload = (event) => {
|
||||
const fileUploaded = event.target.files[0];
|
||||
|
||||
if (fileUploaded == null) return;
|
||||
|
||||
try {
|
||||
uploaddb.mutate(fileUploaded);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
};
|
||||
|
||||
const handleIPC = (action) => {
|
||||
switch (action) {
|
||||
case 'min':
|
||||
ipcRenderer.send('set-window', 'to-tray');
|
||||
break;
|
||||
case 'max':
|
||||
ipcRenderer.send('set-window', 'to-max');
|
||||
break;
|
||||
case 'shutdown':
|
||||
ipcRenderer.send('shutdown', 'now');
|
||||
break;
|
||||
case 'help':
|
||||
ipcRenderer.send('send-to-link', 'help');
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<QuitIconBtn size='md' />
|
||||
<MaxIconBtn size='md' />
|
||||
<MinIconBtn size='md' />
|
||||
<QuitIconBtn size='lg' clickhandler={() => handleIPC('shutdown')} />
|
||||
<MaxIconBtn
|
||||
style={{ fontSize: '1.5em' }}
|
||||
size='lg'
|
||||
clickhandler={() => handleIPC('max')}
|
||||
/>
|
||||
<MinIconBtn
|
||||
style={{ fontSize: '1.5em' }}
|
||||
size='lg'
|
||||
clickhandler={() => handleIPC('min')}
|
||||
/>
|
||||
<div className={style.gap} />
|
||||
<HelpIconBtn size='md' disabled />
|
||||
<SettingsIconBtn size='md' disabled />
|
||||
<InfoIconBtn size='md' clickhandler={onOpen} />
|
||||
<DownloadIconBtn size='md' clickhandler={handleDownload} />
|
||||
<HelpIconBtn
|
||||
style={{ fontSize: '1.5em' }}
|
||||
size='lg'
|
||||
clickhandler={() => handleIPC('help')}
|
||||
/>
|
||||
<SettingsIconBtn style={{ fontSize: '1.5em' }} size='lg' disabled />
|
||||
<div className={style.gap} />
|
||||
<InfoIconBtn
|
||||
style={{ fontSize: '1.5em' }}
|
||||
size='lg'
|
||||
clickhandler={onOpen}
|
||||
/>
|
||||
<input
|
||||
type='file'
|
||||
style={{ display: 'none' }}
|
||||
ref={hiddenFileInput}
|
||||
onChange={handleUpload}
|
||||
accept='.json'
|
||||
/>
|
||||
<UploadIconBtn
|
||||
style={{ fontSize: '1.5em' }}
|
||||
size='lg'
|
||||
clickhandler={handleClick}
|
||||
/>
|
||||
<DownloadIconBtn
|
||||
style={{ fontSize: '1.5em' }}
|
||||
size='lg'
|
||||
clickhandler={handleDownload}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -10,9 +10,6 @@ export default function DownloadIconBtn(props) {
|
||||
size={props.size || 'xs'}
|
||||
icon={<FiDownload />}
|
||||
colorScheme='white'
|
||||
variant='outline'
|
||||
isRound
|
||||
borderColor='#fff1'
|
||||
onClick={clickhandler}
|
||||
_focus={{ boxShadow: 'none' }}
|
||||
{...rest}
|
||||
|
||||
@@ -10,9 +10,6 @@ export default function HelpIconBtn(props) {
|
||||
size={props.size || 'xs'}
|
||||
icon={<FiHelpCircle />}
|
||||
colorScheme='white'
|
||||
variant='outline'
|
||||
isRound
|
||||
borderColor='#fff1'
|
||||
onClick={clickhandler}
|
||||
_focus={{ boxShadow: 'none' }}
|
||||
{...rest}
|
||||
|
||||
@@ -10,9 +10,6 @@ export default function InfoIconBtn(props) {
|
||||
size={props.size || 'xs'}
|
||||
icon={<FiHome />}
|
||||
colorScheme='white'
|
||||
variant='outline'
|
||||
isRound
|
||||
borderColor='#fff1'
|
||||
onClick={clickhandler}
|
||||
_focus={{ boxShadow: 'none' }}
|
||||
{...rest}
|
||||
|
||||
@@ -10,9 +10,6 @@ export default function MaxIconBtn(props) {
|
||||
size={props.size || 'xs'}
|
||||
icon={<FiMaximize />}
|
||||
colorScheme='white'
|
||||
variant='outline'
|
||||
isRound
|
||||
borderColor='#fff1'
|
||||
onClick={clickhandler}
|
||||
_focus={{ boxShadow: 'none' }}
|
||||
{...rest}
|
||||
|
||||
@@ -10,9 +10,6 @@ export default function MinIconBtn(props) {
|
||||
size={props.size || 'xs'}
|
||||
icon={<FiMinimize />}
|
||||
colorScheme='white'
|
||||
variant='outline'
|
||||
isRound
|
||||
borderColor='#fff1'
|
||||
onClick={clickhandler}
|
||||
_focus={{ boxShadow: 'none' }}
|
||||
{...rest}
|
||||
|
||||
@@ -1,21 +1,68 @@
|
||||
import { IconButton } from '@chakra-ui/button';
|
||||
import { Button, IconButton } from '@chakra-ui/button';
|
||||
import {
|
||||
AlertDialog,
|
||||
AlertDialogBody,
|
||||
AlertDialogContent,
|
||||
AlertDialogFooter,
|
||||
AlertDialogHeader,
|
||||
AlertDialogOverlay,
|
||||
} from '@chakra-ui/modal';
|
||||
import { Tooltip } from '@chakra-ui/tooltip';
|
||||
import { useRef, useState } from 'react';
|
||||
import { FiPower } from 'react-icons/fi';
|
||||
|
||||
export default function QuitIconBtn(props) {
|
||||
const { clickhandler, ...rest } = props;
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const onClose = () => setIsOpen(false);
|
||||
const cancelRef = useRef();
|
||||
|
||||
const handleShutdown = () => {
|
||||
onClose();
|
||||
clickhandler();
|
||||
};
|
||||
|
||||
return (
|
||||
<Tooltip label='Quit Application'>
|
||||
<IconButton
|
||||
size={props.size || 'xs'}
|
||||
icon={<FiPower />}
|
||||
colorScheme='red'
|
||||
variant='outline'
|
||||
isRound
|
||||
onClick={clickhandler}
|
||||
_focus={{ boxShadow: 'none' }}
|
||||
{...rest}
|
||||
/>
|
||||
</Tooltip>
|
||||
<>
|
||||
<Tooltip label='Quit Application'>
|
||||
<IconButton
|
||||
size={props.size || 'xs'}
|
||||
icon={<FiPower />}
|
||||
colorScheme='red'
|
||||
variant='outline'
|
||||
isRound
|
||||
onClick={() => setIsOpen(true)}
|
||||
_focus={{ boxShadow: 'none' }}
|
||||
{...rest}
|
||||
/>
|
||||
</Tooltip>
|
||||
<AlertDialog
|
||||
isOpen={isOpen}
|
||||
leastDestructiveRef={cancelRef}
|
||||
onClose={onClose}
|
||||
>
|
||||
<AlertDialogOverlay>
|
||||
<AlertDialogContent>
|
||||
<AlertDialogHeader fontSize='lg' fontWeight='bold'>
|
||||
Server Shutdown
|
||||
</AlertDialogHeader>
|
||||
|
||||
<AlertDialogBody>
|
||||
This will shutdown the program and all running servers. Are you
|
||||
sure?
|
||||
</AlertDialogBody>
|
||||
|
||||
<AlertDialogFooter>
|
||||
<Button ref={cancelRef} onClick={onClose}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button colorScheme='red' onClick={handleShutdown} ml={3}>
|
||||
Shutdown
|
||||
</Button>
|
||||
</AlertDialogFooter>
|
||||
</AlertDialogContent>
|
||||
</AlertDialogOverlay>
|
||||
</AlertDialog>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -10,9 +10,6 @@ export default function SettingsIconBtn(props) {
|
||||
size={props.size || 'xs'}
|
||||
icon={<FiSettings />}
|
||||
colorScheme='white'
|
||||
variant='outline'
|
||||
isRound
|
||||
borderColor='#fff1'
|
||||
onClick={clickhandler}
|
||||
_focus={{ boxShadow: 'none' }}
|
||||
{...rest}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
import { IconButton } from '@chakra-ui/button';
|
||||
import { Tooltip } from '@chakra-ui/tooltip';
|
||||
import { FiUpload } from 'react-icons/fi';
|
||||
|
||||
export default function UploadIconBtn(props) {
|
||||
const { clickhandler, ...rest } = props;
|
||||
return (
|
||||
<Tooltip label='Upload File'>
|
||||
<IconButton
|
||||
size={props.size || 'xs'}
|
||||
icon={<FiUpload />}
|
||||
colorScheme='white'
|
||||
onClick={clickhandler}
|
||||
_focus={{ boxShadow: 'none' }}
|
||||
{...rest}
|
||||
/>
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user