mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-20 22:49:18 +00:00
v2 styling (#263)
* feat: implement progress bar on running event * refactor: use event action hook * refactor: align backend data * style: v2 style tweaks * style: v2 style tweaks + ts <Info> * fix: fix delay increment calls * style: v2 style tweaks + ts <Playback> * style: v2 style tweaks + ts <EventEditor> * style: v2 style tweaks + ts <MessageControl> * fix: naming issue with message control socket endpoint * chore: upgrade style dependencies * style: v2 style tweaks + ts <MenuBar> * style: v2 style tweaks + ts <RundownMenu> * style: v2 style tweaks + ts <Playback> * fix: add selected and next information to EventTimer * style: v2 style tweaks + ts <EventBlock> * style: v2 style tweaks + ts <DelayBlock> * style: v2 style tweaks + ts <BlockBlock> * style: v2 style tweaks + ts <QuickEntry> * refactor: extract <TextInput> logic * chore: upgrade build dependencies * chore: folder structure refactor * fix: issue with dependency path in electron * chore: update version in demo db
This commit is contained in:
@@ -1,6 +1,130 @@
|
||||
@use '../../../theme/main' as *;
|
||||
@use '../../../theme/v2Styles' as *;
|
||||
@use '../blockMixins' as *;
|
||||
|
||||
.eventBlock {
|
||||
@include block-styling;
|
||||
|
||||
display: grid;
|
||||
grid-template-areas:
|
||||
"binder ... ... ..."
|
||||
"binder pb-actions times actions"
|
||||
"binder pb-actions title title"
|
||||
"binder pb-actions estatus estatus"
|
||||
"binder ... ... ...";
|
||||
|
||||
grid-template-columns: $block-binder-width auto 1fr auto;
|
||||
grid-template-rows: 4px 36px 36px 36px 4px;
|
||||
align-items: center;
|
||||
margin: 4px 2px;
|
||||
padding-right: $block-clearance;
|
||||
gap: 2px;
|
||||
|
||||
&.selected {
|
||||
background-color: #101010;
|
||||
}
|
||||
|
||||
&.hasCursor {
|
||||
outline: 1px solid #779BE7;
|
||||
}
|
||||
|
||||
&.skip {
|
||||
border: 1px solid rgba(white, 0.03);
|
||||
box-shadow: none;
|
||||
|
||||
.delayNote,
|
||||
.eventTitle,
|
||||
.eventNote,
|
||||
.binder,
|
||||
.eventTimers,
|
||||
.eventStatus {
|
||||
opacity: $opacity-disabled;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.binder {
|
||||
grid-area: binder;
|
||||
height: 100%;
|
||||
display: grid;
|
||||
place-content: center;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
|
||||
border-radius: $block-border-radius 0 0 $block-border-radius;
|
||||
|
||||
background-color: #303030; // to override inline
|
||||
color: $section-white;
|
||||
font-size: 17px;
|
||||
|
||||
.drag {
|
||||
@include drag-style;
|
||||
position: absolute;
|
||||
margin-top: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.playbackActions {
|
||||
grid-area: pb-actions;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: 0 8px;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.eventTimers {
|
||||
grid-area: times;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: $block-clearance;
|
||||
height: 100%;
|
||||
|
||||
.delayNote {
|
||||
font-size: 12px;
|
||||
line-height: 14px;
|
||||
color: #E69056;
|
||||
}
|
||||
}
|
||||
|
||||
.eventTitle {
|
||||
grid-area: title;
|
||||
display: block;
|
||||
font-size: 18px;
|
||||
|
||||
&.noTitle {
|
||||
.preview {
|
||||
opacity: $opacity-disabled;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.eventActions {
|
||||
grid-area: actions;
|
||||
display: flex;
|
||||
gap: $block-clearance;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
|
||||
.eventOptions {
|
||||
margin: $element-spacing 16px $element-spacing 0;
|
||||
}
|
||||
|
||||
.progressBg {
|
||||
grid-area: progb;
|
||||
border-radius: 2px;
|
||||
background-color: #282828;
|
||||
opacity: 1;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.progressBg.hidden {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.flip {
|
||||
transform: rotateY(180deg);
|
||||
}
|
||||
|
||||
.statusElements {
|
||||
grid-area: estatus;
|
||||
display: grid;
|
||||
@@ -9,189 +133,40 @@
|
||||
"progb progb";
|
||||
gap: 2px;
|
||||
grid-template-rows: auto 4px;
|
||||
|
||||
.eventNote {
|
||||
grid-area: notes;
|
||||
display: block;
|
||||
font-size: 15px;
|
||||
color: $notes-color;
|
||||
line-height: 15px;
|
||||
}
|
||||
|
||||
.eventStatus {
|
||||
grid-area: status;
|
||||
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: $element-spacing;
|
||||
|
||||
.statusIcon {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border-radius: 12px;
|
||||
padding: 4px;
|
||||
color: $text-gray-disabled;
|
||||
}
|
||||
|
||||
.statusIcon.statusNext {
|
||||
border: 1px solid transparent;
|
||||
|
||||
&.enabled {
|
||||
color: $text-white;
|
||||
background-color: $ontime-accent;
|
||||
}
|
||||
}
|
||||
|
||||
.statusIcon.statusDelay {
|
||||
&.enabled {
|
||||
color: $text-white;
|
||||
background-color: $ontime-delay;
|
||||
}
|
||||
}
|
||||
|
||||
.statusIcon.statusPublic {
|
||||
&.enabled {
|
||||
color: $text-white;
|
||||
background-color: $ontime-roll;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.eventBlock {
|
||||
// layout
|
||||
display: grid;
|
||||
grid-template-areas:
|
||||
"binder pb-actions times actions"
|
||||
"binder pb-actions title title"
|
||||
"binder pb-actions estatus estatus";
|
||||
grid-template-columns: $binder-width auto 1fr auto;
|
||||
grid-template-rows: 36px 36px 36px;
|
||||
align-items: center;
|
||||
margin: 4px 2px;
|
||||
padding-right: $clearance;
|
||||
|
||||
// style - general
|
||||
border-radius: $block-border-radius;
|
||||
gap: 2px;
|
||||
|
||||
// style - colour
|
||||
background-color: $bg-container-l2;
|
||||
border: $border-l3;
|
||||
|
||||
// variant
|
||||
&.selected {
|
||||
background-color: $bg-container-l3;
|
||||
}
|
||||
|
||||
&.skip {
|
||||
background-color: $bg-gray-1000;
|
||||
border: 1px solid transparent;
|
||||
|
||||
.eventTimers > .delayNote,
|
||||
.eventTitle,
|
||||
.eventNote {
|
||||
color: $text-gray-disabled;
|
||||
}
|
||||
|
||||
.binder,
|
||||
.eventTimers,
|
||||
.eventStatus {
|
||||
opacity: $opacity-disabled;
|
||||
}
|
||||
}
|
||||
|
||||
.binder {
|
||||
// layout
|
||||
grid-area: binder;
|
||||
height: 100%;
|
||||
display: grid;
|
||||
place-content: center;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
|
||||
// style - general
|
||||
border-radius: 3px 0 0 3px;
|
||||
border-right: 1px solid $bg-gray-900;
|
||||
|
||||
// style - colour
|
||||
background-color: $bg-container-l3; // override inline
|
||||
color: $text-white;
|
||||
|
||||
.drag {
|
||||
@include drag-style;
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
|
||||
.playbackActions {
|
||||
// layout
|
||||
grid-area: pb-actions;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: $element-spacing $clearance $element-spacing $element-spacing;
|
||||
// style - general
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.eventTimers {
|
||||
grid-area: times;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: $clearance;
|
||||
height: 100%;
|
||||
|
||||
.delayNote {
|
||||
font-size: 11px;
|
||||
color: $text-delay;
|
||||
}
|
||||
}
|
||||
|
||||
.eventTitle {
|
||||
grid-area: title;
|
||||
display: block;
|
||||
font-size: 18px;
|
||||
|
||||
.eventTitle__preview {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&.noTitle {
|
||||
span {
|
||||
opacity: $opacity-disabled;
|
||||
}
|
||||
}
|
||||
|
||||
input {
|
||||
border-radius: 2px;
|
||||
border: 1px;
|
||||
}
|
||||
}
|
||||
|
||||
.eventActions {
|
||||
grid-area: actions;
|
||||
|
||||
display: flex;
|
||||
gap: $element-spacing;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
|
||||
.eventOptions {
|
||||
margin: $element-spacing 16px $element-spacing 0;
|
||||
}
|
||||
}
|
||||
|
||||
.progressBg {
|
||||
grid-area: progb;
|
||||
border-radius: 1px;
|
||||
background-color: $bg-container-l1;
|
||||
opacity: 1;
|
||||
|
||||
// layout
|
||||
height: 100%;
|
||||
padding: 2px 0;
|
||||
}
|
||||
|
||||
.progressBg.hidden {
|
||||
opacity: 0;
|
||||
}
|
||||
.eventNote {
|
||||
grid-area: notes;
|
||||
display: block;
|
||||
font-size: 13px;
|
||||
color: $block-text-color;
|
||||
line-height: 13px;
|
||||
}
|
||||
|
||||
.eventStatus {
|
||||
grid-area: status;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 8px;
|
||||
|
||||
.statusIcon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
color: #404040;
|
||||
}
|
||||
|
||||
.statusNext.enabled {
|
||||
color: $playback-start;
|
||||
}
|
||||
|
||||
.statusDelay.enabled {
|
||||
color: $ontime-delay;
|
||||
}
|
||||
|
||||
.statusPublic.enabled {
|
||||
color: $action-blue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,17 +4,16 @@ import { Editable, EditableInput, EditablePreview, Tooltip } from '@chakra-ui/re
|
||||
import { FiUsers } from '@react-icons/all-files/fi/FiUsers';
|
||||
import { IoOptions } from '@react-icons/all-files/io5/IoOptions';
|
||||
import { IoPlay } from '@react-icons/all-files/io5/IoPlay';
|
||||
import { IoPlayBackOutline } from '@react-icons/all-files/io5/IoPlayBackOutline';
|
||||
import { IoPlayOutline } from '@react-icons/all-files/io5/IoPlayOutline';
|
||||
import { IoPlaySkipForward } from '@react-icons/all-files/io5/IoPlaySkipForward';
|
||||
import { IoReload } from '@react-icons/all-files/io5/IoReload';
|
||||
import { IoRemoveCircle } from '@react-icons/all-files/io5/IoRemoveCircle';
|
||||
import { IoRemoveCircleOutline } from '@react-icons/all-files/io5/IoRemoveCircleOutline';
|
||||
import { IoReorderTwo } from '@react-icons/all-files/io5/IoReorderTwo';
|
||||
import { IoReturnDownForward } from '@react-icons/all-files/io5/IoReturnDownForward';
|
||||
import { IoTimerOutline } from '@react-icons/all-files/io5/IoTimerOutline';
|
||||
import { editorEventId } from 'common/atoms/LocalEventSettings';
|
||||
import TooltipActionBtn from 'common/components/buttons/TooltipActionBtn';
|
||||
import { getAccessibleColour } from 'common/utils/styleUtils';
|
||||
import { cx, getAccessibleColour } from 'common/utils/styleUtils';
|
||||
import { useAtom } from 'jotai';
|
||||
|
||||
import { useEventAction } from '../../../common/hooks/useEventAction';
|
||||
@@ -23,7 +22,7 @@ import { Playstate } from '../../../common/models/OntimeTypes';
|
||||
import { tooltipDelayMid } from '../../../ontimeConfig';
|
||||
import { EventItemActions } from '../RundownEntry';
|
||||
|
||||
import EventBlockActionMenu from './composite/EventBlockActionMenu';
|
||||
import BlockActionMenu from './composite/BlockActionMenu';
|
||||
import EventBlockProgressBar from './composite/EventBlockProgressBar';
|
||||
import EventBlockTimers from './composite/EventBlockTimers';
|
||||
|
||||
@@ -31,9 +30,6 @@ import style from './EventBlock.module.scss';
|
||||
|
||||
const blockBtnStyle = {
|
||||
size: 'sm',
|
||||
colorScheme: 'white',
|
||||
variant: 'ghost',
|
||||
fontSize: '20px',
|
||||
};
|
||||
|
||||
const tooltipProps = {
|
||||
@@ -56,8 +52,9 @@ interface EventBlockProps {
|
||||
next: boolean;
|
||||
skip: boolean;
|
||||
selected: boolean;
|
||||
hasCursor: boolean;
|
||||
playback?: Playstate;
|
||||
actionHandler: (action: EventItemActions, payload: any) => void;
|
||||
actionHandler: (action: EventItemActions, payload?: any) => void;
|
||||
}
|
||||
|
||||
export default function EventBlock(props: EventBlockProps) {
|
||||
@@ -77,6 +74,7 @@ export default function EventBlock(props: EventBlockProps) {
|
||||
next,
|
||||
skip = false,
|
||||
selected,
|
||||
hasCursor,
|
||||
playback,
|
||||
actionHandler,
|
||||
} = props;
|
||||
@@ -89,6 +87,7 @@ export default function EventBlock(props: EventBlockProps) {
|
||||
const hasDelay = delay !== 0 && delay !== null;
|
||||
|
||||
// Todo: could I re-render the item without causing a state change here?
|
||||
// ?? use refs instead?
|
||||
useEffect(() => {
|
||||
setBlockTitle(title);
|
||||
}, [title]);
|
||||
@@ -115,13 +114,18 @@ export default function EventBlock(props: EventBlockProps) {
|
||||
playBtnStyles._hover = {};
|
||||
}
|
||||
|
||||
const blockClasses = cx([
|
||||
style.eventBlock,
|
||||
skip ? style.skip : null,
|
||||
selected ? style.selected : null,
|
||||
hasCursor ? style.hasCursor : null,
|
||||
]);
|
||||
|
||||
return (
|
||||
<Draggable key={eventId} draggableId={eventId} index={index}>
|
||||
{(provided) => (
|
||||
<div
|
||||
className={`${style.eventBlock} ${skip ? style.skip : ''} ${
|
||||
selected ? style.selected : ''
|
||||
}`}
|
||||
className={blockClasses}
|
||||
{...provided.draggableProps}
|
||||
ref={provided.innerRef}
|
||||
>
|
||||
@@ -138,36 +142,38 @@ export default function EventBlock(props: EventBlockProps) {
|
||||
</div>
|
||||
<div className={style.playbackActions}>
|
||||
<TooltipActionBtn
|
||||
variant='ontime-subtle-white'
|
||||
aria-label='Skip event'
|
||||
tooltip='Skip event'
|
||||
openDelay={tooltipDelayMid}
|
||||
icon={skip ? <IoRemoveCircle /> : <IoRemoveCircleOutline />}
|
||||
{...blockBtnStyle}
|
||||
variant={skip ? 'solid' : 'ghost'}
|
||||
clickHandler={() => actionHandler('update', { field: 'skip', value: !skip })}
|
||||
tabIndex={-1}
|
||||
disabled={selected}
|
||||
/>
|
||||
<TooltipActionBtn
|
||||
variant='ontime-subtle-white'
|
||||
aria-label='Load event'
|
||||
tooltip='Load event'
|
||||
openDelay={tooltipDelayMid}
|
||||
icon={selected ? <IoPlayBackOutline /> : <IoReload />}
|
||||
icon={<IoReload className={style.flip} />}
|
||||
disabled={skip}
|
||||
{...blockBtnStyle}
|
||||
clickHandler={() => setEventPlayback.loadEvent(eventId)}
|
||||
tabIndex={-1}
|
||||
/>
|
||||
<TooltipActionBtn
|
||||
variant='ontime-subtle-white'
|
||||
aria-label='Start event'
|
||||
tooltip='Start event'
|
||||
openDelay={tooltipDelayMid}
|
||||
icon={eventIsPlaying ? <IoPlay /> : <IoPlayOutline />}
|
||||
disabled={skip}
|
||||
{...blockBtnStyle}
|
||||
variant={eventIsPlaying ? 'solid' : 'ghost'}
|
||||
clickHandler={() => setEventPlayback.startEvent(eventId)}
|
||||
backgroundColor={eventIsPlaying ? '#58A151' : undefined}
|
||||
_hover={{backgroundColor: eventIsPlaying ? '#58A151' : undefined}}
|
||||
tabIndex={-1}
|
||||
/>
|
||||
</div>
|
||||
@@ -186,7 +192,7 @@ export default function EventBlock(props: EventBlockProps) {
|
||||
onChange={(value) => setBlockTitle(value)}
|
||||
onSubmit={(value) => handleTitle(value)}
|
||||
>
|
||||
<EditablePreview className={style.eventTitle__preview} />
|
||||
<EditablePreview className={style.preview} />
|
||||
<EditableInput />
|
||||
</Editable>
|
||||
<div className={style.statusElements}>
|
||||
@@ -195,54 +201,53 @@ export default function EventBlock(props: EventBlockProps) {
|
||||
<EventBlockProgressBar playback={playback} />
|
||||
</div>
|
||||
<div className={style.eventStatus}>
|
||||
<Tooltip label='Next event' isDisabled={!next} {...tooltipProps}>
|
||||
<span
|
||||
className={`${style.statusIcon} ${style.statusNext} ${next ? style.enabled : ''}`}
|
||||
<Tooltip
|
||||
label='Next event'
|
||||
isDisabled={!next}
|
||||
shouldWrapChildren {...tooltipProps}
|
||||
>
|
||||
<IoReturnDownForward />
|
||||
</span>
|
||||
<IoPlaySkipForward
|
||||
className={`${style.statusIcon} ${style.statusNext} ${next ? style.enabled : ''}`} />
|
||||
</Tooltip>
|
||||
<Tooltip label='Event has delay' isDisabled={!hasDelay} {...tooltipProps}>
|
||||
<span
|
||||
className={`${style.statusIcon} ${style.statusDelay} ${
|
||||
hasDelay ? style.enabled : ''
|
||||
}`}
|
||||
<Tooltip
|
||||
label='Event has delay'
|
||||
isDisabled={!hasDelay}
|
||||
shouldWrapChildren {...tooltipProps}
|
||||
>
|
||||
<IoTimerOutline />
|
||||
</span>
|
||||
<IoTimerOutline className={`${style.statusIcon} ${style.statusDelay} ${
|
||||
hasDelay ? style.enabled : ''
|
||||
}`} />
|
||||
</Tooltip>
|
||||
<Tooltip
|
||||
label={`${isPublic ? 'Event is public' : 'Event is private'}`}
|
||||
{...tooltipProps}
|
||||
shouldWrapChildren
|
||||
>
|
||||
<span
|
||||
className={`${style.statusIcon} ${style.statusPublic} ${
|
||||
<FiUsers className={`${style.statusIcon} ${style.statusPublic} ${
|
||||
isPublic ? style.enabled : ''
|
||||
}`}
|
||||
>
|
||||
<FiUsers />
|
||||
</span>
|
||||
}`} />
|
||||
</Tooltip>
|
||||
</div>
|
||||
</div>
|
||||
<div className={style.eventActions}>
|
||||
<TooltipActionBtn
|
||||
{...blockBtnStyle}
|
||||
variant='ontime-subtle-white'
|
||||
size='sm'
|
||||
icon={<IoOptions />}
|
||||
clickHandler={() => setOpenId((prev) => prev === eventId ? null : eventId)}
|
||||
tooltip='Event options'
|
||||
aria-label='Event options'
|
||||
tabIndex={-1}
|
||||
backgroundColor={openId === eventId ? '#ebedf0' : 'transparent'}
|
||||
color={openId === eventId ? '#333' : '#ebedf0'}
|
||||
_hover={{ bg: '#ebedf0', color: '#333' }}
|
||||
backgroundColor={openId === eventId ? '#2B5ABC' : undefined}
|
||||
color={openId === eventId ? 'white' : '#f6f6f6'}
|
||||
/>
|
||||
<EventBlockActionMenu
|
||||
<BlockActionMenu
|
||||
showAdd
|
||||
showDelay
|
||||
showBlock
|
||||
showClone
|
||||
enableDelete
|
||||
actionHandler={actionHandler}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
import {
|
||||
IconButton,
|
||||
Menu,
|
||||
MenuButton,
|
||||
MenuDivider,
|
||||
MenuItem,
|
||||
MenuList,
|
||||
Tooltip,
|
||||
} from '@chakra-ui/react';
|
||||
import { IoAdd } from '@react-icons/all-files/io5/IoAdd';
|
||||
import { IoDuplicateOutline } from '@react-icons/all-files/io5/IoDuplicateOutline';
|
||||
import { IoRemoveCircleOutline } from '@react-icons/all-files/io5/IoRemoveCircleOutline';
|
||||
import { IoTimerOutline } from '@react-icons/all-files/io5/IoTimerOutline';
|
||||
import { IoTrashBinSharp } from '@react-icons/all-files/io5/IoTrashBinSharp';
|
||||
|
||||
import { tooltipDelayMid } from '../../../../ontimeConfig';
|
||||
import { EventItemActions } from '../../RundownEntry';
|
||||
|
||||
interface BlockActionMenuProps {
|
||||
showAdd?: boolean;
|
||||
showDelay?: boolean;
|
||||
showBlock?: boolean;
|
||||
enableDelete?: boolean;
|
||||
showClone?: boolean;
|
||||
actionHandler: (action: EventItemActions, payload?: any) => void;
|
||||
className?: string;
|
||||
}
|
||||
export default function BlockActionMenu(props: BlockActionMenuProps) {
|
||||
const { showAdd, showDelay, showBlock, enableDelete, showClone, actionHandler, className } = props;
|
||||
|
||||
return (
|
||||
<Menu isLazy lazyBehavior='unmount' variant='ontime-on-dark'>
|
||||
<Tooltip label='Add ...' openDelay={tooltipDelayMid}>
|
||||
<MenuButton
|
||||
as={IconButton}
|
||||
aria-label='Event options'
|
||||
icon={<IoAdd />}
|
||||
tabIndex={-1}
|
||||
variant='ontime-subtle'
|
||||
color='#f6f6f6'
|
||||
size='sm'
|
||||
className={className}
|
||||
/>
|
||||
</Tooltip>
|
||||
<MenuList>
|
||||
<MenuItem icon={<IoAdd />} onClick={() => actionHandler('event')} isDisabled={!showAdd}>
|
||||
Add Event after
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
icon={<IoTimerOutline />}
|
||||
onClick={() => actionHandler('delay')}
|
||||
isDisabled={!showDelay}
|
||||
>
|
||||
Add Delay after
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
icon={<IoRemoveCircleOutline />}
|
||||
onClick={() => actionHandler('block')}
|
||||
isDisabled={!showBlock}
|
||||
>
|
||||
Add Block after
|
||||
</MenuItem>
|
||||
{showClone && (
|
||||
<MenuItem
|
||||
icon={<IoDuplicateOutline />}
|
||||
onClick={() => actionHandler('clone')}
|
||||
isDisabled={!showBlock}
|
||||
>
|
||||
Clone event
|
||||
</MenuItem>
|
||||
)}
|
||||
<MenuDivider />
|
||||
<MenuItem
|
||||
icon={<IoTrashBinSharp />}
|
||||
onClick={() => actionHandler('delete')}
|
||||
isDisabled={!enableDelete}
|
||||
color='#D20300'
|
||||
>
|
||||
Delete event
|
||||
</MenuItem>
|
||||
</MenuList>
|
||||
</Menu>
|
||||
);
|
||||
}
|
||||
@@ -1,87 +0,0 @@
|
||||
import {
|
||||
Divider,
|
||||
IconButton,
|
||||
Menu,
|
||||
MenuButton,
|
||||
MenuItem,
|
||||
MenuList,
|
||||
Tooltip,
|
||||
} from '@chakra-ui/react';
|
||||
import { FiMinusCircle } from '@react-icons/all-files/fi/FiMinusCircle';
|
||||
import { FiPlus } from '@react-icons/all-files/fi/FiPlus';
|
||||
import { FiTrash2 } from '@react-icons/all-files/fi/FiTrash2';
|
||||
import { IoDuplicateOutline } from '@react-icons/all-files/io5/IoDuplicateOutline';
|
||||
import { IoTimerOutline } from '@react-icons/all-files/io5/IoTimerOutline';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { tooltipDelayMid } from '../../../../ontimeConfig';
|
||||
|
||||
|
||||
export default function EventBlockActionMenu(props) {
|
||||
const { showAdd, showDelay, showBlock, showClone, actionHandler } = props;
|
||||
|
||||
const menuStyle = {
|
||||
color: '#000000',
|
||||
backgroundColor: 'rgba(255,255,255,1)',
|
||||
};
|
||||
|
||||
const blockBtnStyle = {
|
||||
size: 'sm',
|
||||
variant: 'outline',
|
||||
colorScheme: 'whiteAlpha',
|
||||
};
|
||||
|
||||
return (
|
||||
<Menu isLazy lazyBehavior='unmount'>
|
||||
<Tooltip label='Add ...' delay={tooltipDelayMid}>
|
||||
<MenuButton as={IconButton} aria-label='Options' icon={<FiPlus />}
|
||||
tabIndex={-1} {...blockBtnStyle} />
|
||||
</Tooltip>
|
||||
<MenuList style={menuStyle}>
|
||||
<MenuItem icon={<FiPlus />} onClick={() => actionHandler('event')} isDisabled={!showAdd}>
|
||||
Add Event after
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
icon={<IoTimerOutline />}
|
||||
onClick={() => actionHandler('delay')}
|
||||
isDisabled={!showDelay}
|
||||
>
|
||||
Add Delay after
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
icon={<FiMinusCircle />}
|
||||
onClick={() => actionHandler('block')}
|
||||
isDisabled={!showBlock}
|
||||
>
|
||||
Add Block after
|
||||
</MenuItem>
|
||||
{showClone && (
|
||||
<MenuItem
|
||||
icon={<IoDuplicateOutline />}
|
||||
onClick={() => actionHandler('clone')}
|
||||
isDisabled={!showBlock}
|
||||
>
|
||||
Clone event
|
||||
</MenuItem>
|
||||
)}
|
||||
<Divider />
|
||||
<MenuItem
|
||||
icon={<FiTrash2 />}
|
||||
onClick={() => actionHandler('delete')}
|
||||
isDisabled={!showBlock}
|
||||
color='red.500'
|
||||
>
|
||||
Delete event
|
||||
</MenuItem>
|
||||
</MenuList>
|
||||
</Menu>
|
||||
);
|
||||
}
|
||||
|
||||
EventBlockActionMenu.propTypes = {
|
||||
showAdd: PropTypes.bool,
|
||||
showDelay: PropTypes.bool,
|
||||
showBlock: PropTypes.bool,
|
||||
showClone: PropTypes.bool,
|
||||
actionHandler: PropTypes.func,
|
||||
};
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useCallback, useContext } from 'react';
|
||||
import TimeInput from 'common/components/input/TimeInput';
|
||||
import TimeInput from 'common/components/input/time-input/TimeInput';
|
||||
import { LoggingContext } from 'common/context/LoggingContext';
|
||||
import { millisToMinutes } from 'common/utils/dateConfig';
|
||||
import { stringFromMillis } from 'common/utils/time';
|
||||
|
||||
Reference in New Issue
Block a user