mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-20 22:49:18 +00:00
style: small tweaks on blocks
This commit is contained in:
@@ -144,7 +144,7 @@ $playback-width: 450px;
|
|||||||
.eventEditor {
|
.eventEditor {
|
||||||
border-radius: 8px 8px 0 0;
|
border-radius: 8px 8px 0 0;
|
||||||
background-color: $bg-container-l2;
|
background-color: $bg-container-l2;
|
||||||
box-shadow: rgba(0, 0, 0, 0.35) 0 3px 6px 6px;
|
box-shadow: rgba(0, 0, 0, 0.6) 0 3px 6px 6px;
|
||||||
border-top: 1px solid $white-10;
|
border-top: 1px solid $white-10;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
|
|||||||
@@ -8,13 +8,13 @@ $block-clearance: 8px;
|
|||||||
$block-border-radius: 8px;
|
$block-border-radius: 8px;
|
||||||
$block-text-color: $gray-50;
|
$block-text-color: $gray-50;
|
||||||
$block-bg: $gray-1200;
|
$block-bg: $gray-1200;
|
||||||
|
$block-bg2: $gray-1050; // for delay and blocks
|
||||||
$block-box-shadow: rgba(0, 0, 0, 0.5) 0 0 3px 2px;
|
$block-box-shadow: rgba(0, 0, 0, 0.5) 0 0 3px 2px;
|
||||||
$secondary-block-height: 40px;
|
$secondary-block-height: 40px;
|
||||||
$block-cursor-color: $blue-400;
|
$block-cursor-color: $blue-400;
|
||||||
|
|
||||||
@mixin block-styling() {
|
@mixin block-styling() {
|
||||||
box-sizing: content-box;
|
box-sizing: content-box;
|
||||||
background-color: $block-bg;
|
|
||||||
border: 1px solid $white-10;
|
border: 1px solid $white-10;
|
||||||
font-family: $ontime-font-family;
|
font-family: $ontime-font-family;
|
||||||
border-radius: $block-border-radius;
|
border-radius: $block-border-radius;
|
||||||
|
|||||||
@@ -3,12 +3,14 @@
|
|||||||
.block {
|
.block {
|
||||||
@include block-spacing;
|
@include block-spacing;
|
||||||
@include block-styling;
|
@include block-styling;
|
||||||
box-sizing: content-box;
|
|
||||||
|
background-color: $block-bg2;
|
||||||
|
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 32px 1fr auto;
|
grid-template-columns: 32px 1fr auto;
|
||||||
gap: 8px;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
height: $secondary-block-height;
|
height: $secondary-block-height;
|
||||||
|
gap: 8px;
|
||||||
|
|
||||||
&.hasCursor {
|
&.hasCursor {
|
||||||
outline: 1px solid $block-cursor-color;
|
outline: 1px solid $block-cursor-color;
|
||||||
@@ -19,6 +21,6 @@
|
|||||||
@include drag-style;
|
@include drag-style;
|
||||||
}
|
}
|
||||||
|
|
||||||
.actionOverlay {
|
.actionMenu {
|
||||||
justify-self: flex-end;
|
justify-self: flex-end;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ export default function BlockBlock(props: BlockBlockProps) {
|
|||||||
<IoReorderTwo />
|
<IoReorderTwo />
|
||||||
</span>
|
</span>
|
||||||
<EditableBlockTitle title={data.title} eventId={data.id} placeholder='Block title' />
|
<EditableBlockTitle title={data.title} eventId={data.id} placeholder='Block title' />
|
||||||
<BlockActionMenu className={style.actionOverlay} showAdd showDelay enableDelete actionHandler={actionHandler} />
|
<BlockActionMenu className={style.actionMenu} showAdd showDelay enableDelete actionHandler={actionHandler} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
@include block-spacing;
|
@include block-spacing;
|
||||||
@include block-styling;
|
@include block-styling;
|
||||||
|
|
||||||
|
background-color: $block-bg2;
|
||||||
|
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 32px 1fr auto;
|
grid-template-columns: 32px 1fr auto;
|
||||||
grid-template-areas: 'drag inpt btns';
|
grid-template-areas: 'drag inpt btns';
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { Button, HStack } from '@chakra-ui/react';
|
|||||||
import { useSortable } from '@dnd-kit/sortable';
|
import { useSortable } from '@dnd-kit/sortable';
|
||||||
import { CSS } from '@dnd-kit/utilities';
|
import { CSS } from '@dnd-kit/utilities';
|
||||||
import { IoCheckmark } from '@react-icons/all-files/io5/IoCheckmark';
|
import { IoCheckmark } from '@react-icons/all-files/io5/IoCheckmark';
|
||||||
|
import { IoClose } from '@react-icons/all-files/io5/IoClose';
|
||||||
import { IoReorderTwo } from '@react-icons/all-files/io5/IoReorderTwo';
|
import { IoReorderTwo } from '@react-icons/all-files/io5/IoReorderTwo';
|
||||||
import { OntimeDelay, OntimeEvent } from 'ontime-types';
|
import { OntimeDelay, OntimeEvent } from 'ontime-types';
|
||||||
|
|
||||||
@@ -31,7 +32,7 @@ interface DelayBlockProps {
|
|||||||
|
|
||||||
export default function DelayBlock(props: DelayBlockProps) {
|
export default function DelayBlock(props: DelayBlockProps) {
|
||||||
const { data, hasCursor, actionHandler } = props;
|
const { data, hasCursor, actionHandler } = props;
|
||||||
const { applyDelay, updateEvent } = useEventAction();
|
const { applyDelay, updateEvent, deleteEvent } = useEventAction();
|
||||||
const handleRef = useRef<null | HTMLSpanElement>(null);
|
const handleRef = useRef<null | HTMLSpanElement>(null);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@@ -56,9 +57,13 @@ export default function DelayBlock(props: DelayBlockProps) {
|
|||||||
}
|
}
|
||||||
}, [hasCursor]);
|
}, [hasCursor]);
|
||||||
|
|
||||||
const applyDelayHandler = useCallback(() => {
|
const applyDelayHandler = () => {
|
||||||
applyDelay(data.id);
|
applyDelay(data.id);
|
||||||
}, [data.id, applyDelay]);
|
};
|
||||||
|
|
||||||
|
const cancelDelayHandler = () => {
|
||||||
|
deleteEvent(data.id);
|
||||||
|
};
|
||||||
|
|
||||||
const delaySubmitHandler = useCallback(
|
const delaySubmitHandler = useCallback(
|
||||||
(value: number) => {
|
(value: number) => {
|
||||||
@@ -84,7 +89,10 @@ export default function DelayBlock(props: DelayBlockProps) {
|
|||||||
<DelayInput value={delayValue} submitHandler={delaySubmitHandler} />
|
<DelayInput value={delayValue} submitHandler={delaySubmitHandler} />
|
||||||
<HStack spacing='8px' className={style.actionOverlay}>
|
<HStack spacing='8px' className={style.actionOverlay}>
|
||||||
<Button onClick={applyDelayHandler} size='sm' leftIcon={<IoCheckmark />} variant='ontime-subtle-white'>
|
<Button onClick={applyDelayHandler} size='sm' leftIcon={<IoCheckmark />} variant='ontime-subtle-white'>
|
||||||
Apply delay
|
Apply
|
||||||
|
</Button>
|
||||||
|
<Button onClick={cancelDelayHandler} size='sm' leftIcon={<IoClose />} variant='ontime-subtle-white'>
|
||||||
|
Cancel
|
||||||
</Button>
|
</Button>
|
||||||
<BlockActionMenu showAdd enableDelete actionHandler={actionHandler} />
|
<BlockActionMenu showAdd enableDelete actionHandler={actionHandler} />
|
||||||
</HStack>
|
</HStack>
|
||||||
|
|||||||
@@ -2,8 +2,11 @@
|
|||||||
@use '../../../theme/ontimeColours' as *;
|
@use '../../../theme/ontimeColours' as *;
|
||||||
@use '../blockMixins' as *;
|
@use '../blockMixins' as *;
|
||||||
|
|
||||||
|
$skip-opacity: 0.1;
|
||||||
|
|
||||||
.eventBlock {
|
.eventBlock {
|
||||||
@include block-styling;
|
@include block-styling;
|
||||||
|
background-color: $block-bg;
|
||||||
|
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-areas:
|
grid-template-areas:
|
||||||
@@ -29,7 +32,6 @@
|
|||||||
|
|
||||||
&.skip {
|
&.skip {
|
||||||
border: 1px solid $white-3;
|
border: 1px solid $white-3;
|
||||||
box-shadow: none;
|
|
||||||
|
|
||||||
.delayNote,
|
.delayNote,
|
||||||
.eventTitle,
|
.eventTitle,
|
||||||
@@ -37,7 +39,7 @@
|
|||||||
.binder,
|
.binder,
|
||||||
.eventTimers,
|
.eventTimers,
|
||||||
.eventStatus {
|
.eventStatus {
|
||||||
opacity: $opacity-disabled;
|
opacity: $skip-opacity;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import { memo, useCallback, useEffect, useState } from 'react';
|
import { memo, useCallback, useEffect, useState } from 'react';
|
||||||
import { Tooltip } from '@chakra-ui/react';
|
import { Tooltip } from '@chakra-ui/react';
|
||||||
import { IoCaretDownCircle } from '@react-icons/all-files/io5/IoCaretDownCircle';
|
import { IoCaretDown } from '@react-icons/all-files/io5/IoCaretDown';
|
||||||
import { IoCaretUpCircle } from '@react-icons/all-files/io5/IoCaretUpCircle';
|
import { IoCaretUp } from '@react-icons/all-files/io5/IoCaretUp';
|
||||||
import { IoOptions } from '@react-icons/all-files/io5/IoOptions';
|
import { IoOptions } from '@react-icons/all-files/io5/IoOptions';
|
||||||
import { IoPeople } from '@react-icons/all-files/io5/IoPeople';
|
import { IoPeople } from '@react-icons/all-files/io5/IoPeople';
|
||||||
import { IoPlayCircle } from '@react-icons/all-files/io5/IoPlayCircle';
|
import { IoPlay } from '@react-icons/all-files/io5/IoPlay';
|
||||||
import { IoPlayForwardCircle } from '@react-icons/all-files/io5/IoPlayForwardCircle';
|
import { IoPlayForward } from '@react-icons/all-files/io5/IoPlayForward';
|
||||||
import { IoPlaySkipForwardCircle } from '@react-icons/all-files/io5/IoPlaySkipForwardCircle';
|
import { IoPlaySkipForward } from '@react-icons/all-files/io5/IoPlaySkipForward';
|
||||||
import { IoStopCircle } from '@react-icons/all-files/io5/IoStopCircle';
|
import { IoStop } from '@react-icons/all-files/io5/IoStop';
|
||||||
import { IoTime } from '@react-icons/all-files/io5/IoTime';
|
import { IoTime } from '@react-icons/all-files/io5/IoTime';
|
||||||
import { EndAction, Playback, TimerType } from 'ontime-types';
|
import { EndAction, Playback, TimerType } from 'ontime-types';
|
||||||
|
|
||||||
@@ -120,16 +120,16 @@ const EventBlockInner = (props: EventBlockInnerProps) => {
|
|||||||
<span className={style.tag}>NEXT</span>
|
<span className={style.tag}>NEXT</span>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
)}
|
)}
|
||||||
<Tooltip label={`End action: ${endAction}`} {...tooltipProps}>
|
|
||||||
<span>
|
|
||||||
<EndActionIcon action={endAction} className={style.statusIcon} />
|
|
||||||
</span>
|
|
||||||
</Tooltip>
|
|
||||||
<Tooltip label={`Time type: ${timerType}`} {...tooltipProps}>
|
<Tooltip label={`Time type: ${timerType}`} {...tooltipProps}>
|
||||||
<span>
|
<span>
|
||||||
<TimerIcon type={timerType} className={style.statusIcon} />
|
<TimerIcon type={timerType} className={style.statusIcon} />
|
||||||
</span>
|
</span>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
<Tooltip label={`End action: ${endAction}`} {...tooltipProps}>
|
||||||
|
<span>
|
||||||
|
<EndActionIcon action={endAction} className={style.statusIcon} />
|
||||||
|
</span>
|
||||||
|
</Tooltip>
|
||||||
<Tooltip label={`${isPublic ? 'Event is public' : 'Event is private'}`} {...tooltipProps}>
|
<Tooltip label={`${isPublic ? 'Event is public' : 'Event is private'}`} {...tooltipProps}>
|
||||||
<span>
|
<span>
|
||||||
<IoPeople className={`${style.statusIcon} ${isPublic ? style.active : style.disabled}`} />
|
<IoPeople className={`${style.statusIcon} ${isPublic ? style.active : style.disabled}`} />
|
||||||
@@ -161,24 +161,24 @@ export default memo(EventBlockInner);
|
|||||||
function EndActionIcon(props: { action: EndAction; className: string }) {
|
function EndActionIcon(props: { action: EndAction; className: string }) {
|
||||||
const { action, className } = props;
|
const { action, className } = props;
|
||||||
if (action === EndAction.LoadNext) {
|
if (action === EndAction.LoadNext) {
|
||||||
return <IoPlaySkipForwardCircle className={className} />;
|
return <IoPlaySkipForward className={className} />;
|
||||||
}
|
}
|
||||||
if (action === EndAction.PlayNext) {
|
if (action === EndAction.PlayNext) {
|
||||||
return <IoPlayForwardCircle className={className} />;
|
return <IoPlayForward className={className} />;
|
||||||
}
|
}
|
||||||
if (action === EndAction.Stop) {
|
if (action === EndAction.Stop) {
|
||||||
return <IoStopCircle className={className} />;
|
return <IoStop className={className} />;
|
||||||
}
|
}
|
||||||
return <IoPlayCircle className={className} />;
|
return <IoPlay className={className} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
function TimerIcon(props: { type: TimerType; className: string }) {
|
function TimerIcon(props: { type: TimerType; className: string }) {
|
||||||
const { type, className } = props;
|
const { type, className } = props;
|
||||||
if (type === TimerType.CountUp) {
|
if (type === TimerType.CountUp) {
|
||||||
return <IoCaretUpCircle className={className} />;
|
return <IoCaretUp className={className} />;
|
||||||
}
|
}
|
||||||
if (type === TimerType.Clock) {
|
if (type === TimerType.Clock) {
|
||||||
return <IoTime className={className} />;
|
return <IoTime className={className} />;
|
||||||
}
|
}
|
||||||
return <IoCaretDownCircle className={className} />;
|
return <IoCaretDown className={className} />;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,5 @@
|
|||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
import {
|
import { IconButton, Menu, MenuButton, MenuDivider, MenuItem, MenuList, Tooltip } from '@chakra-ui/react';
|
||||||
IconButton,
|
|
||||||
Menu,
|
|
||||||
MenuButton,
|
|
||||||
MenuDivider,
|
|
||||||
MenuItem,
|
|
||||||
MenuList,
|
|
||||||
Tooltip,
|
|
||||||
} from '@chakra-ui/react';
|
|
||||||
import { IoAdd } from '@react-icons/all-files/io5/IoAdd';
|
import { IoAdd } from '@react-icons/all-files/io5/IoAdd';
|
||||||
import { IoDuplicateOutline } from '@react-icons/all-files/io5/IoDuplicateOutline';
|
import { IoDuplicateOutline } from '@react-icons/all-files/io5/IoDuplicateOutline';
|
||||||
import { IoEllipsisHorizontal } from '@react-icons/all-files/io5/IoEllipsisHorizontal';
|
import { IoEllipsisHorizontal } from '@react-icons/all-files/io5/IoEllipsisHorizontal';
|
||||||
@@ -27,14 +19,15 @@ interface BlockActionMenuProps {
|
|||||||
actionHandler: (action: EventItemActions, payload?: any) => void;
|
actionHandler: (action: EventItemActions, payload?: any) => void;
|
||||||
className?: string;
|
className?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function BlockActionMenu(props: BlockActionMenuProps) {
|
export default function BlockActionMenu(props: BlockActionMenuProps) {
|
||||||
const { showAdd, showDelay, showBlock, enableDelete, showClone, actionHandler, className } = props;
|
const { showAdd, showDelay, showBlock, enableDelete, showClone, actionHandler, className } = props;
|
||||||
|
|
||||||
const handleAddEvent = useCallback(() => actionHandler("event"), [actionHandler])
|
const handleAddEvent = useCallback(() => actionHandler('event'), [actionHandler]);
|
||||||
const handleAddDelay = useCallback(() => actionHandler("delay"), [actionHandler])
|
const handleAddDelay = useCallback(() => actionHandler('delay'), [actionHandler]);
|
||||||
const handleAddBlock = useCallback(() => actionHandler("block"), [actionHandler])
|
const handleAddBlock = useCallback(() => actionHandler('block'), [actionHandler]);
|
||||||
const handleClone = useCallback(() => actionHandler("clone"), [actionHandler])
|
const handleClone = useCallback(() => actionHandler('clone'), [actionHandler]);
|
||||||
const handleDelete = useCallback(() => actionHandler("delete"), [actionHandler])
|
const handleDelete = useCallback(() => actionHandler('delete'), [actionHandler]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Menu isLazy lazyBehavior='unmount' variant='ontime-on-dark'>
|
<Menu isLazy lazyBehavior='unmount' variant='ontime-on-dark'>
|
||||||
@@ -44,8 +37,7 @@ export default function BlockActionMenu(props: BlockActionMenuProps) {
|
|||||||
aria-label='Event options'
|
aria-label='Event options'
|
||||||
icon={<IoEllipsisHorizontal />}
|
icon={<IoEllipsisHorizontal />}
|
||||||
tabIndex={-1}
|
tabIndex={-1}
|
||||||
variant='ontime-subtle'
|
variant='ontime-subtle-white'
|
||||||
color='#f6f6f6'
|
|
||||||
size='sm'
|
size='sm'
|
||||||
className={className}
|
className={className}
|
||||||
/>
|
/>
|
||||||
@@ -54,36 +46,19 @@ export default function BlockActionMenu(props: BlockActionMenuProps) {
|
|||||||
<MenuItem icon={<IoAdd />} onClick={handleAddEvent} isDisabled={!showAdd}>
|
<MenuItem icon={<IoAdd />} onClick={handleAddEvent} isDisabled={!showAdd}>
|
||||||
Add Event after
|
Add Event after
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem
|
<MenuItem icon={<IoTimerOutline />} onClick={handleAddDelay} isDisabled={!showDelay}>
|
||||||
icon={<IoTimerOutline />}
|
|
||||||
onClick={handleAddDelay}
|
|
||||||
isDisabled={!showDelay}
|
|
||||||
>
|
|
||||||
Add Delay after
|
Add Delay after
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem
|
<MenuItem icon={<IoRemoveCircleOutline />} onClick={handleAddBlock} isDisabled={!showBlock}>
|
||||||
icon={<IoRemoveCircleOutline />}
|
|
||||||
onClick={handleAddBlock}
|
|
||||||
isDisabled={!showBlock}
|
|
||||||
>
|
|
||||||
Add Block after
|
Add Block after
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
{showClone && (
|
{showClone && (
|
||||||
<MenuItem
|
<MenuItem icon={<IoDuplicateOutline />} onClick={handleClone} isDisabled={!showBlock}>
|
||||||
icon={<IoDuplicateOutline />}
|
|
||||||
onClick={handleClone}
|
|
||||||
isDisabled={!showBlock}
|
|
||||||
>
|
|
||||||
Clone event
|
Clone event
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
)}
|
)}
|
||||||
<MenuDivider />
|
<MenuDivider />
|
||||||
<MenuItem
|
<MenuItem icon={<IoTrashBinSharp />} onClick={handleDelete} isDisabled={!enableDelete} color='#D20300'>
|
||||||
icon={<IoTrashBinSharp />}
|
|
||||||
onClick={handleDelete}
|
|
||||||
isDisabled={!enableDelete}
|
|
||||||
color='#D20300'
|
|
||||||
>
|
|
||||||
Delete event
|
Delete event
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
</MenuList>
|
</MenuList>
|
||||||
|
|||||||
@@ -42,6 +42,8 @@ const EventBlockPlayback = (props: EventBlockPlaybackProps) => {
|
|||||||
aria-label='Skip event'
|
aria-label='Skip event'
|
||||||
tooltip='Skip event'
|
tooltip='Skip event'
|
||||||
icon={skip ? <IoRemoveCircle /> : <IoRemoveCircleOutline />}
|
icon={skip ? <IoRemoveCircle /> : <IoRemoveCircleOutline />}
|
||||||
|
backgroundColor={skip ? '#FA5656' : undefined}
|
||||||
|
_hover={{ backgroundColor: skip ? '#FF7878' : '#404040' }}
|
||||||
{...tooltipProps}
|
{...tooltipProps}
|
||||||
{...blockBtnStyle}
|
{...blockBtnStyle}
|
||||||
clickHandler={toggleSkip}
|
clickHandler={toggleSkip}
|
||||||
|
|||||||
Reference in New Issue
Block a user