mirror of
https://github.com/cpvalente/ontime.git
synced 2026-09-02 04:49:05 +00:00
refactor: expose editor panels in small device
This commit is contained in:
committed by
Carlos Valente
parent
b991627cb7
commit
984dcb0181
@@ -18,7 +18,7 @@ import ViewLoader from './views/ViewLoader';
|
|||||||
import { ONTIME_VERSION } from './ONTIME_VERSION';
|
import { ONTIME_VERSION } from './ONTIME_VERSION';
|
||||||
import { sentryDsn, sentryRecommendedIgnore } from './sentry.config';
|
import { sentryDsn, sentryRecommendedIgnore } from './sentry.config';
|
||||||
|
|
||||||
const Editor = React.lazy(() => import('./features/editors/ProtectedEditor'));
|
const Editor = React.lazy(() => import('./views/editor/ProtectedEditor'));
|
||||||
const Cuesheet = React.lazy(() => import('./views/cuesheet/ProtectedCuesheet'));
|
const Cuesheet = React.lazy(() => import('./views/cuesheet/ProtectedCuesheet'));
|
||||||
const Operator = React.lazy(() => import('./features/operator/OperatorExport'));
|
const Operator = React.lazy(() => import('./features/operator/OperatorExport'));
|
||||||
|
|
||||||
|
|||||||
@@ -53,14 +53,46 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.destructive {
|
||||||
|
background: $red-700;
|
||||||
|
color: $ui-white;
|
||||||
|
|
||||||
|
&:hover:not(:disabled):not(:active) {
|
||||||
|
background: $red-600;
|
||||||
|
color: $ui-white;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active:not(:disabled) {
|
||||||
|
background: $red-800;
|
||||||
|
border-color: $red-900;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.subtle-destructive {
|
||||||
|
background: $gray-1050;
|
||||||
|
color: $red-400;
|
||||||
|
|
||||||
|
&:hover:not(:disabled):not(:active) {
|
||||||
|
background: $gray-1000;
|
||||||
|
color: $red-500;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active:not(:disabled) {
|
||||||
|
background: $gray-1100;
|
||||||
|
border-color: $gray-1250;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.medium {
|
.medium {
|
||||||
height: 2rem;
|
height: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.large {
|
.large {
|
||||||
height: 2.5rem;
|
height: 2.5rem;
|
||||||
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
.xlarge {
|
.xlarge {
|
||||||
height: 3rem;
|
height: 3rem;
|
||||||
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { cx } from '../../utils/styleUtils';
|
|||||||
import style from './Button.module.scss';
|
import style from './Button.module.scss';
|
||||||
|
|
||||||
interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
||||||
variant?: 'subtle' | 'primary';
|
variant?: 'subtle' | 'primary' | 'destructive' | 'subtle-destructive';
|
||||||
size?: 'medium' | 'large' | 'xlarge';
|
size?: 'medium' | 'large' | 'xlarge';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,8 +16,22 @@
|
|||||||
border: 1px solid $gray-1200;
|
border: 1px solid $gray-1200;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.backdrop {
|
||||||
|
position: fixed;
|
||||||
|
inset: 0;
|
||||||
|
z-index: $zindex-backdrop;
|
||||||
|
background-color: $backdrop-color;
|
||||||
|
transition: opacity 300ms cubic-bezier(0.45, 1.005, 0, 1.005);
|
||||||
|
|
||||||
|
&[data-starting-style],
|
||||||
|
&[data-ending-style] {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
font-size: 1.25rem;
|
font-size: 1rem;
|
||||||
|
font-weight: 600;
|
||||||
padding-block: 1rem;
|
padding-block: 1rem;
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
@@ -10,12 +10,21 @@ interface DialogProps {
|
|||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
title: string;
|
title: string;
|
||||||
showCloseButton?: boolean;
|
showCloseButton?: boolean;
|
||||||
|
showBackdrop?: boolean;
|
||||||
bodyElements: ReactNode;
|
bodyElements: ReactNode;
|
||||||
footerElements: ReactNode;
|
footerElements: ReactNode;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Dialog({ isOpen, title, showCloseButton, bodyElements, footerElements, onClose }: DialogProps) {
|
export default function Dialog({
|
||||||
|
isOpen,
|
||||||
|
title,
|
||||||
|
showCloseButton,
|
||||||
|
showBackdrop,
|
||||||
|
bodyElements,
|
||||||
|
footerElements,
|
||||||
|
onClose,
|
||||||
|
}: DialogProps) {
|
||||||
return (
|
return (
|
||||||
<BaseDialog.Root
|
<BaseDialog.Root
|
||||||
open={isOpen}
|
open={isOpen}
|
||||||
@@ -24,6 +33,7 @@ export default function Dialog({ isOpen, title, showCloseButton, bodyElements, f
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<BaseDialog.Portal>
|
<BaseDialog.Portal>
|
||||||
|
{showBackdrop && <BaseDialog.Backdrop className={style.backdrop} />}
|
||||||
<BaseDialog.Popup className={style.dialog}>
|
<BaseDialog.Popup className={style.dialog}>
|
||||||
<div className={style.title}>
|
<div className={style.title}>
|
||||||
{title}
|
{title}
|
||||||
|
|||||||
+6
@@ -40,3 +40,9 @@
|
|||||||
margin-bottom: $element-inner-spacing;
|
margin-bottom: $element-inner-spacing;
|
||||||
max-width: max-content; // prevent label from taking entire row
|
max-width: max-content; // prevent label from taking entire row
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.separator {
|
||||||
|
width: 1px;
|
||||||
|
height: 0.75em;
|
||||||
|
background-color: $border-color-ondark;
|
||||||
|
}
|
||||||
+5
-1
@@ -2,7 +2,7 @@ import type { HTMLAttributes, LabelHTMLAttributes } from 'react';
|
|||||||
import { IconBaseProps } from 'react-icons';
|
import { IconBaseProps } from 'react-icons';
|
||||||
import { IoArrowUp } from 'react-icons/io5';
|
import { IoArrowUp } from 'react-icons/io5';
|
||||||
|
|
||||||
import { cx } from '../../../common/utils/styleUtils';
|
import { cx } from '../../utils/styleUtils';
|
||||||
|
|
||||||
import style from './EditorUtils.module.scss';
|
import style from './EditorUtils.module.scss';
|
||||||
|
|
||||||
@@ -27,3 +27,7 @@ export function Label({ children, className, ...elementProps }: LabelHTMLAttribu
|
|||||||
</label>
|
</label>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function Separator({ className, ...elementProps }: HTMLAttributes<HTMLDivElement>) {
|
||||||
|
return <div className={cx([style.separator, className])} {...elementProps} />;
|
||||||
|
}
|
||||||
@@ -3,7 +3,6 @@ import { create } from 'zustand';
|
|||||||
export enum AppMode {
|
export enum AppMode {
|
||||||
Run = 'run',
|
Run = 'run',
|
||||||
Edit = 'edit',
|
Edit = 'edit',
|
||||||
Freeze = 'freeze',
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const appModeKey = 'ontime-app-mode';
|
const appModeKey = 'ontime-app-mode';
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
import { IoEye, IoEyeOffOutline } from 'react-icons/io5';
|
import { IoEye, IoEyeOffOutline } from 'react-icons/io5';
|
||||||
|
|
||||||
import TooltipActionBtn from '../../../common/components/buttons/TooltipActionBtn';
|
import TooltipActionBtn from '../../../common/components/buttons/TooltipActionBtn';
|
||||||
import { setMessage, useExternalMessageInput as useSecondaryMessageInput, useTimerMessageInput } from '../../../common/hooks/useSocket';
|
import {
|
||||||
|
setMessage,
|
||||||
|
useExternalMessageInput as useSecondaryMessageInput,
|
||||||
|
useTimerMessageInput,
|
||||||
|
} from '../../../common/hooks/useSocket';
|
||||||
import { tooltipDelayMid } from '../../../ontimeConfig';
|
import { tooltipDelayMid } from '../../../ontimeConfig';
|
||||||
|
|
||||||
import InputRow from './InputRow';
|
import InputRow from './InputRow';
|
||||||
|
|||||||
+2
-2
@@ -1,15 +1,15 @@
|
|||||||
import { memo } from 'react';
|
import { memo } from 'react';
|
||||||
|
|
||||||
|
import { Corner } from '../../../common/components/editor-utils/EditorUtils';
|
||||||
import ErrorBoundary from '../../../common/components/error-boundary/ErrorBoundary';
|
import ErrorBoundary from '../../../common/components/error-boundary/ErrorBoundary';
|
||||||
import ViewNavigationMenu from '../../../common/components/navigation-menu/ViewNavigationMenu';
|
import ViewNavigationMenu from '../../../common/components/navigation-menu/ViewNavigationMenu';
|
||||||
import ProtectRoute from '../../../common/components/protect-route/ProtectRoute';
|
import ProtectRoute from '../../../common/components/protect-route/ProtectRoute';
|
||||||
import { handleLinks } from '../../../common/utils/linkUtils';
|
import { handleLinks } from '../../../common/utils/linkUtils';
|
||||||
import { cx } from '../../../common/utils/styleUtils';
|
import { cx } from '../../../common/utils/styleUtils';
|
||||||
import { Corner } from '../../editors/editor-utils/EditorUtils';
|
|
||||||
|
|
||||||
import MessageControl from './MessageControl';
|
import MessageControl from './MessageControl';
|
||||||
|
|
||||||
import style from '../../editors/Editor.module.scss';
|
import style from '../../../views/editor/Editor.module.scss';
|
||||||
|
|
||||||
export default memo(MessageControlExport);
|
export default memo(MessageControlExport);
|
||||||
function MessageControlExport() {
|
function MessageControlExport() {
|
||||||
@@ -2,12 +2,12 @@ import { IoArrowDown, IoArrowUp, IoBan, IoFlag, IoTime } from 'react-icons/io5';
|
|||||||
import { Tooltip } from '@chakra-ui/react';
|
import { Tooltip } from '@chakra-ui/react';
|
||||||
import { TimerPhase, TimerType } from 'ontime-types';
|
import { TimerPhase, TimerType } from 'ontime-types';
|
||||||
|
|
||||||
|
import { Corner } from '../../../common/components/editor-utils/EditorUtils';
|
||||||
import { useMessagePreview } from '../../../common/hooks/useSocket';
|
import { useMessagePreview } from '../../../common/hooks/useSocket';
|
||||||
import useViewSettings from '../../../common/hooks-query/useViewSettings';
|
import useViewSettings from '../../../common/hooks-query/useViewSettings';
|
||||||
import { handleLinks } from '../../../common/utils/linkUtils';
|
import { handleLinks } from '../../../common/utils/linkUtils';
|
||||||
import { cx, timerPlaceholder } from '../../../common/utils/styleUtils';
|
import { cx, timerPlaceholder } from '../../../common/utils/styleUtils';
|
||||||
import { tooltipDelayMid } from '../../../ontimeConfig';
|
import { tooltipDelayMid } from '../../../ontimeConfig';
|
||||||
import { Corner } from '../../editors/editor-utils/EditorUtils';
|
|
||||||
|
|
||||||
import style from './MessageControl.module.scss';
|
import style from './MessageControl.module.scss';
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
import { memo } from 'react';
|
import { memo } from 'react';
|
||||||
|
|
||||||
|
import { Corner } from '../../../common/components/editor-utils/EditorUtils';
|
||||||
import ErrorBoundary from '../../../common/components/error-boundary/ErrorBoundary';
|
import ErrorBoundary from '../../../common/components/error-boundary/ErrorBoundary';
|
||||||
import ViewNavigationMenu from '../../../common/components/navigation-menu/ViewNavigationMenu';
|
import ViewNavigationMenu from '../../../common/components/navigation-menu/ViewNavigationMenu';
|
||||||
import ProtectRoute from '../../../common/components/protect-route/ProtectRoute';
|
import ProtectRoute from '../../../common/components/protect-route/ProtectRoute';
|
||||||
import { handleLinks } from '../../../common/utils/linkUtils';
|
import { handleLinks } from '../../../common/utils/linkUtils';
|
||||||
import { Corner } from '../../editors/editor-utils/EditorUtils';
|
|
||||||
|
|
||||||
import PlaybackControl from './PlaybackControl';
|
import PlaybackControl from './PlaybackControl';
|
||||||
|
|
||||||
import style from '../../editors/Editor.module.scss';
|
import style from '../../../views/editor/Editor.module.scss';
|
||||||
|
|
||||||
export default memo(TimerControlExport);
|
export default memo(TimerControlExport);
|
||||||
function TimerControlExport() {
|
function TimerControlExport() {
|
||||||
|
|||||||
@@ -7,5 +7,5 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
gap: 2rem;
|
gap: 1rem;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,11 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
padding-inline: 1rem;
|
padding-inline: 1rem;
|
||||||
|
|
||||||
|
:is([data-target='small-device']) & {
|
||||||
|
padding-inline: 0;
|
||||||
|
overflow-x: auto;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.empty {
|
.empty {
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import { IoAdd } from 'react-icons/io5';
|
import { IoAdd } from 'react-icons/io5';
|
||||||
import { Button } from '@chakra-ui/react';
|
|
||||||
import { SupportedEntry } from 'ontime-types';
|
import { SupportedEntry } from 'ontime-types';
|
||||||
|
|
||||||
|
import Button from '../../common/components/buttons/Button';
|
||||||
|
import * as Editor from '../../common/components/editor-utils/EditorUtils';
|
||||||
import Empty from '../../common/components/state/Empty';
|
import Empty from '../../common/components/state/Empty';
|
||||||
|
|
||||||
import style from './Empty.module.scss';
|
import style from './Empty.module.scss';
|
||||||
@@ -17,12 +18,15 @@ export default function RundownEmpty(props: RundownEmptyProps) {
|
|||||||
<div className={style.empty}>
|
<div className={style.empty}>
|
||||||
<Empty style={{ marginTop: '5vh', marginBottom: '3rem' }} />
|
<Empty style={{ marginTop: '5vh', marginBottom: '3rem' }} />
|
||||||
<div className={style.inline}>
|
<div className={style.inline}>
|
||||||
<Button onClick={() => handleAddNew(SupportedEntry.Event)} variant='ontime-filled' leftIcon={<IoAdd />}>
|
<Button onClick={() => handleAddNew(SupportedEntry.Event)} variant='primary' size='large'>
|
||||||
|
<IoAdd />
|
||||||
Create Event
|
Create Event
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<Button onClick={() => handleAddNew(SupportedEntry.Block)} variant='ontime-filled' leftIcon={<IoAdd />}>
|
<Editor.Separator />
|
||||||
Create Block
|
|
||||||
|
<Button onClick={() => handleAddNew(SupportedEntry.Block)} variant='primary' size='large'>
|
||||||
|
<IoAdd /> Create Block
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
@use '../editors/EditorMixin' as editor;
|
@use '../../views/editor/EditorMixin' as editor;
|
||||||
|
|
||||||
.rundownExport {
|
.rundownExport {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { memo } from 'react';
|
import { memo } from 'react';
|
||||||
|
|
||||||
import { ContextMenu } from '../../common/components/context-menu/ContextMenu';
|
import { ContextMenu } from '../../common/components/context-menu/ContextMenu';
|
||||||
|
import { Corner } from '../../common/components/editor-utils/EditorUtils';
|
||||||
import ErrorBoundary from '../../common/components/error-boundary/ErrorBoundary';
|
import ErrorBoundary from '../../common/components/error-boundary/ErrorBoundary';
|
||||||
import ViewNavigationMenu from '../../common/components/navigation-menu/ViewNavigationMenu';
|
import ViewNavigationMenu from '../../common/components/navigation-menu/ViewNavigationMenu';
|
||||||
import ProtectRoute from '../../common/components/protect-route/ProtectRoute';
|
import ProtectRoute from '../../common/components/protect-route/ProtectRoute';
|
||||||
@@ -8,7 +9,6 @@ import { useIsSmallDevice } from '../../common/hooks/useIsSmallDevice';
|
|||||||
import { useAppMode } from '../../common/stores/appModeStore';
|
import { useAppMode } from '../../common/stores/appModeStore';
|
||||||
import { handleLinks } from '../../common/utils/linkUtils';
|
import { handleLinks } from '../../common/utils/linkUtils';
|
||||||
import { cx } from '../../common/utils/styleUtils';
|
import { cx } from '../../common/utils/styleUtils';
|
||||||
import { Corner } from '../editors/editor-utils/EditorUtils';
|
|
||||||
|
|
||||||
import RundownEventEditor from './event-editor/RundownEventEditor';
|
import RundownEventEditor from './event-editor/RundownEventEditor';
|
||||||
import FinderPlacement from './placements/FinderPlacement';
|
import FinderPlacement from './placements/FinderPlacement';
|
||||||
@@ -26,13 +26,17 @@ function RundownExport() {
|
|||||||
if (isSmallDevice && isExtracted) {
|
if (isSmallDevice && isExtracted) {
|
||||||
return (
|
return (
|
||||||
<ProtectRoute permission='editor'>
|
<ProtectRoute permission='editor'>
|
||||||
<div className={cx([style.rundownExport, style.extracted])} data-testid='panel-rundown'>
|
<div
|
||||||
|
className={cx([style.rundownExport, style.extracted])}
|
||||||
|
data-target='small-device'
|
||||||
|
data-testid='panel-rundown'
|
||||||
|
>
|
||||||
<FinderPlacement />
|
<FinderPlacement />
|
||||||
<ViewNavigationMenu supressSettings />
|
<ViewNavigationMenu supressSettings />
|
||||||
<div className={style.content}>
|
<div className={style.content}>
|
||||||
<ErrorBoundary>
|
<ErrorBoundary>
|
||||||
<ContextMenu>
|
<ContextMenu>
|
||||||
<RundownWrapper />
|
<RundownWrapper isSmallDevice />
|
||||||
</ContextMenu>
|
</ContextMenu>
|
||||||
</ErrorBoundary>
|
</ErrorBoundary>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -2,16 +2,21 @@ import Empty from '../../common/components/state/Empty';
|
|||||||
import useRundown from '../../common/hooks-query/useRundown';
|
import useRundown from '../../common/hooks-query/useRundown';
|
||||||
|
|
||||||
import RundownHeader from './rundown-header/RundownHeader';
|
import RundownHeader from './rundown-header/RundownHeader';
|
||||||
|
import RundownHeaderMobile from './rundown-header/RundownHeaderMobile';
|
||||||
import Rundown from './Rundown';
|
import Rundown from './Rundown';
|
||||||
|
|
||||||
import styles from './Rundown.module.scss';
|
import styles from './Rundown.module.scss';
|
||||||
|
|
||||||
export default function RundownWrapper() {
|
interface RundownWrapperProps {
|
||||||
|
isSmallDevice?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function RundownWrapper({ isSmallDevice }: RundownWrapperProps) {
|
||||||
const { data, status } = useRundown();
|
const { data, status } = useRundown();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.rundownWrapper}>
|
<div className={styles.rundownWrapper}>
|
||||||
<RundownHeader />
|
{isSmallDevice ? <RundownHeaderMobile /> : <RundownHeader />}
|
||||||
{status === 'success' && data ? <Rundown data={data} /> : <Empty text='Connecting to server' />}
|
{status === 'success' && data ? <Rundown data={data} /> : <Empty text='Connecting to server' />}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
import { OntimeEvent } from 'ontime-types';
|
import { OntimeEvent } from 'ontime-types';
|
||||||
|
|
||||||
|
import * as Editor from '../../../common/components/editor-utils/EditorUtils';
|
||||||
import AppLink from '../../../common/components/link/app-link/AppLink';
|
import AppLink from '../../../common/components/link/app-link/AppLink';
|
||||||
import { useEntryActions } from '../../../common/hooks/useEntryAction';
|
import { useEntryActions } from '../../../common/hooks/useEntryAction';
|
||||||
import useCustomFields from '../../../common/hooks-query/useCustomFields';
|
import useCustomFields from '../../../common/hooks-query/useCustomFields';
|
||||||
import * as Editor from '../../editors/editor-utils/EditorUtils';
|
|
||||||
|
|
||||||
import EventCustom from './composite/EventEditorCustom';
|
import EventCustom from './composite/EventEditorCustom';
|
||||||
import EventEditorTimes from './composite/EventEditorTimes';
|
import EventEditorTimes from './composite/EventEditorTimes';
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { memo, PropsWithChildren } from 'react';
|
import { memo, PropsWithChildren } from 'react';
|
||||||
import { Kbd } from '@chakra-ui/react';
|
import { Kbd } from '@chakra-ui/react';
|
||||||
|
|
||||||
|
import * as Editor from '../../../common/components/editor-utils/EditorUtils';
|
||||||
import { deviceAlt, deviceMod } from '../../../common/utils/deviceUtils';
|
import { deviceAlt, deviceMod } from '../../../common/utils/deviceUtils';
|
||||||
import * as Editor from '../../editors/editor-utils/EditorUtils';
|
|
||||||
|
|
||||||
import style from './EventEditorEmpty.module.scss';
|
import style from './EventEditorEmpty.module.scss';
|
||||||
|
|
||||||
|
|||||||
@@ -4,10 +4,10 @@ import { Select, Switch, Tooltip } from '@chakra-ui/react';
|
|||||||
import { EndAction, TimerType, TimeStrategy } from 'ontime-types';
|
import { EndAction, TimerType, TimeStrategy } from 'ontime-types';
|
||||||
import { millisToString, parseUserTime } from 'ontime-utils';
|
import { millisToString, parseUserTime } from 'ontime-utils';
|
||||||
|
|
||||||
|
import * as Editor from '../../../../common/components/editor-utils/EditorUtils';
|
||||||
import TimeInput from '../../../../common/components/input/time-input/TimeInput';
|
import TimeInput from '../../../../common/components/input/time-input/TimeInput';
|
||||||
import { useEntryActions } from '../../../../common/hooks/useEntryAction';
|
import { useEntryActions } from '../../../../common/hooks/useEntryAction';
|
||||||
import { millisToDelayString } from '../../../../common/utils/dateConfig';
|
import { millisToDelayString } from '../../../../common/utils/dateConfig';
|
||||||
import * as Editor from '../../../editors/editor-utils/EditorUtils';
|
|
||||||
import TimeInputFlow from '../../time-input-flow/TimeInputFlow';
|
import TimeInputFlow from '../../time-input-flow/TimeInputFlow';
|
||||||
|
|
||||||
import style from '../EventEditor.module.scss';
|
import style from '../EventEditor.module.scss';
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ import { memo } from 'react';
|
|||||||
import { Input } from '@chakra-ui/react';
|
import { Input } from '@chakra-ui/react';
|
||||||
import { sanitiseCue } from 'ontime-utils';
|
import { sanitiseCue } from 'ontime-utils';
|
||||||
|
|
||||||
|
import * as Editor from '../../../../common/components/editor-utils/EditorUtils';
|
||||||
import SwatchSelect from '../../../../common/components/input/colour-input/SwatchSelect';
|
import SwatchSelect from '../../../../common/components/input/colour-input/SwatchSelect';
|
||||||
import * as Editor from '../../../editors/editor-utils/EditorUtils';
|
|
||||||
import { type EditorUpdateFields } from '../EventEditor';
|
import { type EditorUpdateFields } from '../EventEditor';
|
||||||
|
|
||||||
import EventTextArea from './EventTextArea';
|
import EventTextArea from './EventTextArea';
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { type CSSProperties, useCallback, useRef } from 'react';
|
import { type CSSProperties, useCallback, useRef } from 'react';
|
||||||
|
|
||||||
|
import * as Editor from '../../../../common/components/editor-utils/EditorUtils';
|
||||||
import { AutoTextArea } from '../../../../common/components/input/auto-text-area/AutoTextArea';
|
import { AutoTextArea } from '../../../../common/components/input/auto-text-area/AutoTextArea';
|
||||||
import useReactiveTextInput from '../../../../common/components/input/text-input/useReactiveTextInput';
|
import useReactiveTextInput from '../../../../common/components/input/text-input/useReactiveTextInput';
|
||||||
import * as Editor from '../../../editors/editor-utils/EditorUtils';
|
|
||||||
import { EditorUpdateFields } from '../EventEditor';
|
import { EditorUpdateFields } from '../EventEditor';
|
||||||
|
|
||||||
interface CountedTextAreaProps {
|
interface CountedTextAreaProps {
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { useCallback, useRef } from 'react';
|
import { useCallback, useRef } from 'react';
|
||||||
import { Input, InputProps } from '@chakra-ui/react';
|
import { Input, InputProps } from '@chakra-ui/react';
|
||||||
|
|
||||||
|
import * as Editor from '../../../../common/components/editor-utils/EditorUtils';
|
||||||
import useReactiveTextInput from '../../../../common/components/input/text-input/useReactiveTextInput';
|
import useReactiveTextInput from '../../../../common/components/input/text-input/useReactiveTextInput';
|
||||||
import * as Editor from '../../../editors/editor-utils/EditorUtils';
|
|
||||||
import { EditorUpdateFields } from '../EventEditor';
|
import { EditorUpdateFields } from '../EventEditor';
|
||||||
|
|
||||||
interface EventTextInputProps extends InputProps {
|
interface EventTextInputProps extends InputProps {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { memo } from 'react';
|
|||||||
import { useDisclosure } from '@chakra-ui/react';
|
import { useDisclosure } from '@chakra-ui/react';
|
||||||
import { useHotkeys } from '@mantine/hooks';
|
import { useHotkeys } from '@mantine/hooks';
|
||||||
|
|
||||||
import Finder from '../../editors/finder/Finder';
|
import Finder from '../../../views/editor/finder/Finder';
|
||||||
|
|
||||||
export default memo(FinderPlacement);
|
export default memo(FinderPlacement);
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,59 @@
|
|||||||
.header {
|
.header {
|
||||||
padding-inline: 1rem 2rem;
|
padding-inline: calc(2.5rem - 6px) calc(1rem + 2px);
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
gap: 1px;
|
||||||
|
|
||||||
|
:is([data-target='small-device']) & {
|
||||||
|
padding-inline: 0;
|
||||||
|
overflow-x: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.group {
|
||||||
|
display: flex;
|
||||||
|
gap: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: 2rem;
|
||||||
|
padding-inline: 1em;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
border-radius: $component-border-radius-md;
|
||||||
|
color: $gray-400;
|
||||||
|
font-size: calc(1rem - 2px);
|
||||||
|
font-weight: 600;
|
||||||
|
|
||||||
|
&:focus-visible {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover:not(:disabled):not(:active) {
|
||||||
|
background: $gray-1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
background: $gray-1100;
|
||||||
|
}
|
||||||
|
|
||||||
|
&[data-pressed] {
|
||||||
|
background: $blue-700;
|
||||||
|
color: $ui-white;
|
||||||
|
|
||||||
|
&:hover:not(:disabled):not(:active) {
|
||||||
|
background: $blue-600;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.apart {
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.separator {
|
||||||
|
margin-inline: 1rem;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
import { Button, ButtonGroup } from '@chakra-ui/react';
|
import { memo } from 'react';
|
||||||
|
import { Toggle } from '@base-ui-components/react/toggle';
|
||||||
|
import { ToggleGroup } from '@base-ui-components/react/toggle-group';
|
||||||
|
import { Toolbar } from '@base-ui-components/react/toolbar';
|
||||||
import { OffsetMode } from 'ontime-types';
|
import { OffsetMode } from 'ontime-types';
|
||||||
|
|
||||||
|
import * as Editor from '../../../common/components/editor-utils/EditorUtils';
|
||||||
import { setOffsetMode, useOffsetMode } from '../../../common/hooks/useSocket';
|
import { setOffsetMode, useOffsetMode } from '../../../common/hooks/useSocket';
|
||||||
import { AppMode, useAppMode } from '../../../common/stores/appModeStore';
|
import { AppMode, useAppMode } from '../../../common/stores/appModeStore';
|
||||||
|
|
||||||
@@ -8,41 +12,50 @@ import RundownMenu from './RundownMenu';
|
|||||||
|
|
||||||
import style from './RundownHeader.module.scss';
|
import style from './RundownHeader.module.scss';
|
||||||
|
|
||||||
export default function RundownHeader() {
|
export default memo(RundownHeader);
|
||||||
|
function RundownHeader() {
|
||||||
const appMode = useAppMode((state) => state.mode);
|
const appMode = useAppMode((state) => state.mode);
|
||||||
const setAppMode = useAppMode((state) => state.setMode);
|
const setAppMode = useAppMode((state) => state.setMode);
|
||||||
const setRunMode = () => setAppMode(AppMode.Run);
|
|
||||||
const setEditMode = () => setAppMode(AppMode.Edit);
|
|
||||||
|
|
||||||
const { offsetMode } = useOffsetMode();
|
const { offsetMode } = useOffsetMode();
|
||||||
|
|
||||||
|
const toggleAppMode = (mode: AppMode[]) => {
|
||||||
|
// we need to stop user from deselecting a mode
|
||||||
|
const newValue = mode.at(0);
|
||||||
|
if (!newValue) return;
|
||||||
|
setAppMode(newValue);
|
||||||
|
};
|
||||||
|
|
||||||
|
const toggleOffsetMode = (mode: OffsetMode[]) => {
|
||||||
|
// we need to stop user from deselecting a mode
|
||||||
|
const newValue = mode.at(0);
|
||||||
|
if (!newValue) return;
|
||||||
|
setOffsetMode(newValue);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={style.header}>
|
<Toolbar.Root className={style.header}>
|
||||||
<ButtonGroup isAttached>
|
<ToggleGroup value={[appMode]} onValueChange={toggleAppMode} className={style.group}>
|
||||||
<Button size='sm' variant={appMode === AppMode.Run ? 'ontime-filled' : 'ontime-subtle'} onClick={setRunMode}>
|
<Toolbar.Button render={<Toggle />} value={AppMode.Run} className={style.button}>
|
||||||
Run
|
Run
|
||||||
</Button>
|
</Toolbar.Button>
|
||||||
<Button size='sm' variant={appMode === AppMode.Edit ? 'ontime-filled' : 'ontime-subtle'} onClick={setEditMode}>
|
<Toolbar.Button render={<Toggle />} value={AppMode.Edit} className={style.button}>
|
||||||
Edit
|
Edit
|
||||||
</Button>
|
</Toolbar.Button>
|
||||||
</ButtonGroup>
|
</ToggleGroup>
|
||||||
<ButtonGroup isAttached>
|
|
||||||
<Button
|
<Editor.Separator className={style.separator} />
|
||||||
size='sm'
|
|
||||||
variant={offsetMode === OffsetMode.Absolute ? 'ontime-filled' : 'ontime-subtle'}
|
<ToggleGroup value={[offsetMode]} onValueChange={toggleOffsetMode} className={style.group}>
|
||||||
onClick={() => setOffsetMode(OffsetMode.Absolute)}
|
<Toolbar.Button render={<Toggle />} value={OffsetMode.Absolute} className={style.button}>
|
||||||
>
|
|
||||||
Absolute
|
Absolute
|
||||||
</Button>
|
</Toolbar.Button>
|
||||||
<Button
|
<Toolbar.Button render={<Toggle />} value={OffsetMode.Relative} className={style.button}>
|
||||||
size='sm'
|
|
||||||
variant={offsetMode === OffsetMode.Relative ? 'ontime-filled' : 'ontime-subtle'}
|
|
||||||
onClick={() => setOffsetMode(OffsetMode.Relative)}
|
|
||||||
>
|
|
||||||
Relative
|
Relative
|
||||||
</Button>
|
</Toolbar.Button>
|
||||||
</ButtonGroup>
|
</ToggleGroup>
|
||||||
|
|
||||||
<RundownMenu />
|
<RundownMenu />
|
||||||
</div>
|
</Toolbar.Root>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,57 @@
|
|||||||
|
import { memo } from 'react';
|
||||||
|
import { Toggle } from '@base-ui-components/react/toggle';
|
||||||
|
import { ToggleGroup } from '@base-ui-components/react/toggle-group';
|
||||||
|
import { Toolbar } from '@base-ui-components/react/toolbar';
|
||||||
|
import { OffsetMode } from 'ontime-types';
|
||||||
|
|
||||||
|
import * as Editor from '../../../common/components/editor-utils/EditorUtils';
|
||||||
|
import { setOffsetMode, useOffsetMode } from '../../../common/hooks/useSocket';
|
||||||
|
import { AppMode, useAppMode } from '../../../common/stores/appModeStore';
|
||||||
|
|
||||||
|
import style from './RundownHeader.module.scss';
|
||||||
|
|
||||||
|
export default memo(RundownHeader);
|
||||||
|
function RundownHeader() {
|
||||||
|
const appMode = useAppMode((state) => state.mode);
|
||||||
|
const setAppMode = useAppMode((state) => state.setMode);
|
||||||
|
|
||||||
|
const { offsetMode } = useOffsetMode();
|
||||||
|
|
||||||
|
const toggleAppMode = (mode: AppMode[]) => {
|
||||||
|
// we need to stop user from deselecting a mode
|
||||||
|
const newValue = mode.at(0);
|
||||||
|
if (!newValue) return;
|
||||||
|
setAppMode(newValue);
|
||||||
|
};
|
||||||
|
|
||||||
|
const toggleOffsetMode = (mode: OffsetMode[]) => {
|
||||||
|
// we need to stop user from deselecting a mode
|
||||||
|
const newValue = mode.at(0);
|
||||||
|
if (!newValue) return;
|
||||||
|
setOffsetMode(newValue);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Toolbar.Root className={style.header}>
|
||||||
|
<ToggleGroup value={[appMode]} onValueChange={toggleAppMode} className={style.group}>
|
||||||
|
<Toolbar.Button render={<Toggle />} value={AppMode.Run} className={style.button}>
|
||||||
|
Run
|
||||||
|
</Toolbar.Button>
|
||||||
|
<Toolbar.Button render={<Toggle />} value={AppMode.Edit} className={style.button}>
|
||||||
|
Edit
|
||||||
|
</Toolbar.Button>
|
||||||
|
</ToggleGroup>
|
||||||
|
|
||||||
|
<Editor.Separator className={style.separator} />
|
||||||
|
|
||||||
|
<ToggleGroup value={[offsetMode]} onValueChange={toggleOffsetMode} className={style.group}>
|
||||||
|
<Toolbar.Button render={<Toggle />} value={OffsetMode.Absolute} className={style.button}>
|
||||||
|
Absolute
|
||||||
|
</Toolbar.Button>
|
||||||
|
<Toolbar.Button render={<Toggle />} value={OffsetMode.Relative} className={style.button}>
|
||||||
|
Relative
|
||||||
|
</Toolbar.Button>
|
||||||
|
</ToggleGroup>
|
||||||
|
</Toolbar.Root>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,66 +1,62 @@
|
|||||||
import { useCallback, useRef } from 'react';
|
import { memo, useCallback } from 'react';
|
||||||
import { IoTrash } from 'react-icons/io5';
|
import { IoTrash } from 'react-icons/io5';
|
||||||
import {
|
import { useDisclosure } from '@mantine/hooks';
|
||||||
AlertDialog,
|
|
||||||
AlertDialogBody,
|
|
||||||
AlertDialogContent,
|
|
||||||
AlertDialogFooter,
|
|
||||||
AlertDialogHeader,
|
|
||||||
AlertDialogOverlay,
|
|
||||||
Button,
|
|
||||||
useDisclosure,
|
|
||||||
} from '@chakra-ui/react';
|
|
||||||
|
|
||||||
|
import Button from '../../../common/components/buttons/Button';
|
||||||
|
import Dialog from '../../../common/components/dialog/Dialog';
|
||||||
import { useEntryActions } from '../../../common/hooks/useEntryAction';
|
import { useEntryActions } from '../../../common/hooks/useEntryAction';
|
||||||
import { useAppMode } from '../../../common/stores/appModeStore';
|
import { AppMode, useAppMode } from '../../../common/stores/appModeStore';
|
||||||
import { useEventSelection } from '../useEventSelection';
|
import { useEventSelection } from '../useEventSelection';
|
||||||
|
|
||||||
export default function RundownMenu() {
|
import style from './RundownHeader.module.scss';
|
||||||
|
|
||||||
|
export default memo(RundownMenu);
|
||||||
|
function RundownMenu() {
|
||||||
|
const [isOpen, handlers] = useDisclosure();
|
||||||
|
|
||||||
const clearSelectedEvents = useEventSelection((state) => state.clearSelectedEvents);
|
const clearSelectedEvents = useEventSelection((state) => state.clearSelectedEvents);
|
||||||
const appMode = useAppMode((state) => state.mode);
|
const appMode = useAppMode((state) => state.mode);
|
||||||
const { deleteAllEntries } = useEntryActions();
|
const { deleteAllEntries } = useEntryActions();
|
||||||
|
|
||||||
const { isOpen, onOpen, onClose } = useDisclosure();
|
|
||||||
const cancelRef = useRef<HTMLButtonElement | null>(null);
|
|
||||||
|
|
||||||
const deleteAll = useCallback(() => {
|
const deleteAll = useCallback(() => {
|
||||||
deleteAllEntries();
|
deleteAllEntries();
|
||||||
clearSelectedEvents();
|
clearSelectedEvents();
|
||||||
onClose();
|
handlers.close();
|
||||||
}, [clearSelectedEvents, deleteAllEntries, onClose]);
|
}, [clearSelectedEvents, deleteAllEntries, handlers]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Button
|
<Button
|
||||||
size='sm'
|
variant='subtle-destructive'
|
||||||
variant='ontime-outlined'
|
className={style.apart}
|
||||||
leftIcon={<IoTrash />}
|
onClick={() => handlers.open()}
|
||||||
onClick={onOpen}
|
disabled={appMode === AppMode.Run}
|
||||||
color='#FA5656'
|
|
||||||
isDisabled={appMode === 'run'}
|
|
||||||
>
|
>
|
||||||
Clear rundown
|
<IoTrash />
|
||||||
|
Clear All
|
||||||
</Button>
|
</Button>
|
||||||
<AlertDialog variant='ontime' isOpen={isOpen} leastDestructiveRef={cancelRef} onClose={onClose}>
|
<Dialog
|
||||||
<AlertDialogOverlay>
|
isOpen={isOpen}
|
||||||
<AlertDialogContent>
|
onClose={handlers.close}
|
||||||
<AlertDialogHeader fontSize='lg' fontWeight='bold'>
|
title='Clear Rundown'
|
||||||
Clear rundown
|
showBackdrop
|
||||||
</AlertDialogHeader>
|
showCloseButton
|
||||||
<AlertDialogBody>
|
bodyElements={
|
||||||
You will lose all data in your rundown. <br /> Are you sure?
|
<>
|
||||||
</AlertDialogBody>
|
You will lose all data in your rundown. <br /> Are you sure?
|
||||||
<AlertDialogFooter>
|
</>
|
||||||
<Button ref={cancelRef} onClick={onClose} variant='ontime-ghosted-white'>
|
}
|
||||||
Cancel
|
footerElements={
|
||||||
</Button>
|
<>
|
||||||
<Button colorScheme='red' onClick={deleteAll} ml={4}>
|
<Button size='large' onClick={handlers.close}>
|
||||||
Delete all
|
Cancel
|
||||||
</Button>
|
</Button>
|
||||||
</AlertDialogFooter>
|
<Button variant='destructive' size='large' onClick={deleteAll}>
|
||||||
</AlertDialogContent>
|
Delete all
|
||||||
</AlertDialogOverlay>
|
</Button>
|
||||||
</AlertDialog>
|
</>
|
||||||
|
}
|
||||||
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,11 +4,11 @@ import { InputRightElement, Tooltip } from '@chakra-ui/react';
|
|||||||
import { TimeField, TimeStrategy } from 'ontime-types';
|
import { TimeField, TimeStrategy } from 'ontime-types';
|
||||||
import { dayInMs } from 'ontime-utils';
|
import { dayInMs } from 'ontime-utils';
|
||||||
|
|
||||||
|
import * as Editor from '../../../common/components/editor-utils/EditorUtils';
|
||||||
import TimeInputWithButton from '../../../common/components/input/time-input/TimeInputWithButton';
|
import TimeInputWithButton from '../../../common/components/input/time-input/TimeInputWithButton';
|
||||||
import { useEntryActions } from '../../../common/hooks/useEntryAction';
|
import { useEntryActions } from '../../../common/hooks/useEntryAction';
|
||||||
import { cx } from '../../../common/utils/styleUtils';
|
import { cx } from '../../../common/utils/styleUtils';
|
||||||
import { tooltipDelayFast, tooltipDelayMid } from '../../../ontimeConfig';
|
import { tooltipDelayFast, tooltipDelayMid } from '../../../ontimeConfig';
|
||||||
import * as Editor from '../../editors/editor-utils/EditorUtils';
|
|
||||||
|
|
||||||
import style from './TimeInputFlow.module.scss';
|
import style from './TimeInputFlow.module.scss';
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -3,7 +3,7 @@ import { Button, Checkbox } from '@chakra-ui/react';
|
|||||||
import { Column } from '@tanstack/react-table';
|
import { Column } from '@tanstack/react-table';
|
||||||
import { OntimeEntry } from 'ontime-types';
|
import { OntimeEntry } from 'ontime-types';
|
||||||
|
|
||||||
import * as Editor from '../../../../features/editors/editor-utils/EditorUtils';
|
import * as Editor from '../../../../common/components/editor-utils/EditorUtils';
|
||||||
|
|
||||||
import style from './CuesheetTableSettings.module.scss';
|
import style from './CuesheetTableSettings.module.scss';
|
||||||
|
|
||||||
|
|||||||
+6
-6
@@ -6,17 +6,17 @@ import { useHotkeys } from '@mantine/hooks';
|
|||||||
import NavigationMenu from '../../common/components/navigation-menu/NavigationMenu';
|
import NavigationMenu from '../../common/components/navigation-menu/NavigationMenu';
|
||||||
import { useElectronListener } from '../../common/hooks/useElectronEvent';
|
import { useElectronListener } from '../../common/hooks/useElectronEvent';
|
||||||
import { useWindowTitle } from '../../common/hooks/useWindowTitle';
|
import { useWindowTitle } from '../../common/hooks/useWindowTitle';
|
||||||
import AppSettings from '../app-settings/AppSettings';
|
import AppSettings from '../../features/app-settings/AppSettings';
|
||||||
import useAppSettingsNavigation from '../app-settings/useAppSettingsNavigation';
|
import useAppSettingsNavigation from '../../features/app-settings/useAppSettingsNavigation';
|
||||||
import { EditorOverview } from '../overview/Overview';
|
import { EditorOverview } from '../../features/overview/Overview';
|
||||||
|
|
||||||
import WelcomePlacement from './welcome/WelcomePlacement';
|
import WelcomePlacement from './welcome/WelcomePlacement';
|
||||||
|
|
||||||
import styles from './Editor.module.scss';
|
import styles from './Editor.module.scss';
|
||||||
|
|
||||||
const Rundown = lazy(() => import('../rundown/RundownExport'));
|
const Rundown = lazy(() => import('../../features/rundown/RundownExport'));
|
||||||
const TimerControl = lazy(() => import('../control/playback/TimerControlExport'));
|
const TimerControl = lazy(() => import('../../features/control/playback/TimerControlExport'));
|
||||||
const MessageControl = lazy(() => import('../control/message/MessageControlExport'));
|
const MessageControl = lazy(() => import('../../features/control/message/MessageControlExport'));
|
||||||
|
|
||||||
export default function Editor() {
|
export default function Editor() {
|
||||||
const { isOpen: isSettingsOpen, setLocation, close } = useAppSettingsNavigation();
|
const { isOpen: isSettingsOpen, setLocation, close } = useAppSettingsNavigation();
|
||||||
+1
-1
@@ -3,7 +3,7 @@ import { Input, Modal, ModalBody, ModalContent, ModalFooter, ModalOverlay } from
|
|||||||
import { useDebouncedCallback } from '@mantine/hooks';
|
import { useDebouncedCallback } from '@mantine/hooks';
|
||||||
import { SupportedEntry } from 'ontime-types';
|
import { SupportedEntry } from 'ontime-types';
|
||||||
|
|
||||||
import { useEventSelection } from '../../rundown/useEventSelection';
|
import { useEventSelection } from '../../../features/rundown/useEventSelection';
|
||||||
|
|
||||||
import useFinder from './useFinder';
|
import useFinder from './useFinder';
|
||||||
|
|
||||||
+1
-1
@@ -4,9 +4,9 @@ import { Button, Checkbox, Modal, ModalBody, ModalCloseButton, ModalContent, Mod
|
|||||||
import { loadDemo, loadProject } from '../../../common/api/db';
|
import { loadDemo, loadProject } from '../../../common/api/db';
|
||||||
import { postShowWelcomeDialog } from '../../../common/api/settings';
|
import { postShowWelcomeDialog } from '../../../common/api/settings';
|
||||||
import { invalidateAllCaches } from '../../../common/api/utils';
|
import { invalidateAllCaches } from '../../../common/api/utils';
|
||||||
|
import * as Editor from '../../../common/components/editor-utils/EditorUtils';
|
||||||
import ExternalLink from '../../../common/components/link/external-link/ExternalLink';
|
import ExternalLink from '../../../common/components/link/external-link/ExternalLink';
|
||||||
import { appVersion, discordUrl, documentationUrl, websiteUrl } from '../../../externals';
|
import { appVersion, discordUrl, documentationUrl, websiteUrl } from '../../../externals';
|
||||||
import * as Editor from '../editor-utils/EditorUtils';
|
|
||||||
|
|
||||||
import ImportProjectButton from './composite/ImportProjectButton';
|
import ImportProjectButton from './composite/ImportProjectButton';
|
||||||
import WelcomeProjectList from './composite/WelcomeProjectList';
|
import WelcomeProjectList from './composite/WelcomeProjectList';
|
||||||
@@ -14,7 +14,7 @@ test('project file upload', async ({ page }) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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 all' }).click();
|
||||||
await page.getByRole('button', { name: 'Delete all' }).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();
|
||||||
|
|||||||
@@ -5,7 +5,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 all' }).click();
|
||||||
await page.getByRole('button', { name: 'Delete all' }).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();
|
||||||
|
|
||||||
@@ -53,7 +53,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 all' }).click();
|
||||||
await page.getByRole('button', { name: 'Delete all' }).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();
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ test('CRUD operations on the rundown', 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 all' }).click();
|
||||||
await page.getByRole('button', { name: 'Delete all' }).click();
|
await page.getByRole('button', { name: 'Delete all' }).click();
|
||||||
|
|
||||||
// create event from the rundown empty button
|
// create event from the rundown empty button
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ test('smoke test operator', async ({ page }) => {
|
|||||||
// make some boilerplate
|
// make some boilerplate
|
||||||
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 all' }).click();
|
||||||
await page.getByRole('button', { name: 'Delete all' }).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();
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ test('Copy-paste', async ({ page }) => {
|
|||||||
await page.goto('http://localhost:4001/rundown');
|
await page.goto('http://localhost:4001/rundown');
|
||||||
|
|
||||||
// clear rundown
|
// clear rundown
|
||||||
await page.getByRole('button', { name: 'Clear rundown' }).click();
|
await page.getByRole('button', { name: 'Clear all' }).click();
|
||||||
await page.getByRole('button', { name: 'Delete all' }).click();
|
await page.getByRole('button', { name: 'Delete all' }).click();
|
||||||
|
|
||||||
// create event
|
// create event
|
||||||
@@ -43,7 +43,7 @@ test('Move', async ({ page }) => {
|
|||||||
await page.goto('http://localhost:4001/rundown');
|
await page.goto('http://localhost:4001/rundown');
|
||||||
|
|
||||||
// clear rundown
|
// clear rundown
|
||||||
await page.getByRole('button', { name: 'Clear rundown' }).click();
|
await page.getByRole('button', { name: 'Clear all' }).click();
|
||||||
await page.getByRole('button', { name: 'Delete all' }).click();
|
await page.getByRole('button', { name: 'Delete all' }).click();
|
||||||
|
|
||||||
// create events
|
// create events
|
||||||
@@ -67,7 +67,7 @@ test('Add block', async ({ page }) => {
|
|||||||
await page.goto('http://localhost:4001/rundown');
|
await page.goto('http://localhost:4001/rundown');
|
||||||
|
|
||||||
// clear rundown
|
// clear rundown
|
||||||
await page.getByRole('button', { name: 'Clear rundown' }).click();
|
await page.getByRole('button', { name: 'Clear all' }).click();
|
||||||
await page.getByRole('button', { name: 'Delete all' }).click();
|
await page.getByRole('button', { name: 'Delete all' }).click();
|
||||||
|
|
||||||
// create events
|
// create events
|
||||||
@@ -95,7 +95,7 @@ test('Add delay', async ({ page }) => {
|
|||||||
await page.goto('http://localhost:4001/rundown');
|
await page.goto('http://localhost:4001/rundown');
|
||||||
|
|
||||||
// clear rundown
|
// clear rundown
|
||||||
await page.getByRole('button', { name: 'Clear rundown' }).click();
|
await page.getByRole('button', { name: 'Clear all' }).click();
|
||||||
await page.getByRole('button', { name: 'Delete all' }).click();
|
await page.getByRole('button', { name: 'Delete all' }).click();
|
||||||
|
|
||||||
//create events
|
//create events
|
||||||
@@ -116,7 +116,7 @@ test('Add event', async ({ page }) => {
|
|||||||
await page.goto('http://localhost:4001/rundown');
|
await page.goto('http://localhost:4001/rundown');
|
||||||
|
|
||||||
// clear rundown
|
// clear rundown
|
||||||
await page.getByRole('button', { name: 'Clear rundown' }).click();
|
await page.getByRole('button', { name: 'Clear all' }).click();
|
||||||
await page.getByRole('button', { name: 'Delete all' }).click();
|
await page.getByRole('button', { name: 'Delete all' }).click();
|
||||||
|
|
||||||
//create events
|
//create events
|
||||||
@@ -138,7 +138,7 @@ test('Delete event', async ({ page }) => {
|
|||||||
|
|
||||||
// clear rundown
|
// clear rundown
|
||||||
await page.goto('http://localhost:4001/rundown');
|
await page.goto('http://localhost:4001/rundown');
|
||||||
await page.getByRole('button', { name: 'Clear rundown' }).click();
|
await page.getByRole('button', { name: 'Clear all' }).click();
|
||||||
await page.getByRole('button', { name: 'Delete all' }).click();
|
await page.getByRole('button', { name: 'Delete all' }).click();
|
||||||
|
|
||||||
//create event
|
//create event
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { expect, test } from '@playwright/test';
|
|||||||
test('show warning when event crosses midnight', async ({ page }) => {
|
test('show warning when event crosses midnight', async ({ page }) => {
|
||||||
await page.goto('http://localhost:4001/editor');
|
await page.goto('http://localhost:4001/editor');
|
||||||
|
|
||||||
await page.getByRole('button', { name: 'Clear rundown' }).click();
|
await page.getByRole('button', { name: 'Clear all' }).click();
|
||||||
await page.getByRole('button', { name: 'Delete all' }).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();
|
||||||
@@ -23,7 +23,7 @@ test('show warning when event crosses midnight', async ({ page }) => {
|
|||||||
test('show warning when event starts next day midnight', async ({ page }) => {
|
test('show warning when event starts next day midnight', async ({ page }) => {
|
||||||
await page.goto('http://localhost:4001/editor');
|
await page.goto('http://localhost:4001/editor');
|
||||||
|
|
||||||
await page.getByRole('button', { name: 'Clear rundown' }).click();
|
await page.getByRole('button', { name: 'Clear all' }).click();
|
||||||
await page.getByRole('button', { name: 'Delete all' }).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();
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { expect, test } from '@playwright/test';
|
|||||||
test('time until absolute', async ({ page }) => {
|
test('time until absolute', async ({ page }) => {
|
||||||
await page.goto('http://localhost:4001/editor');
|
await page.goto('http://localhost:4001/editor');
|
||||||
|
|
||||||
await page.getByRole('button', { name: 'Clear rundown' }).click();
|
await page.getByRole('button', { name: 'Clear all' }).click();
|
||||||
await page.getByRole('button', { name: 'Delete all' }).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();
|
||||||
@@ -40,7 +40,7 @@ test('time until absolute', async ({ page }) => {
|
|||||||
test('time until relative', async ({ page }) => {
|
test('time until relative', async ({ page }) => {
|
||||||
await page.goto('http://localhost:4001/editor');
|
await page.goto('http://localhost:4001/editor');
|
||||||
|
|
||||||
await page.getByRole('button', { name: 'Clear rundown' }).click();
|
await page.getByRole('button', { name: 'Clear all' }).click();
|
||||||
await page.getByRole('button', { name: 'Delete all' }).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();
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ test('Rearrange while playing', async ({ page }) => {
|
|||||||
await page.goto('http://localhost:4001/rundown');
|
await page.goto('http://localhost:4001/rundown');
|
||||||
|
|
||||||
// clear rundown
|
// clear rundown
|
||||||
await page.getByRole('button', { name: 'Clear rundown' }).click();
|
await page.getByRole('button', { name: 'Clear all' }).click();
|
||||||
await page.getByRole('button', { name: 'Delete all' }).click();
|
await page.getByRole('button', { name: 'Delete all' }).click();
|
||||||
|
|
||||||
// create events
|
// create events
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ const fileToUpload = 'e2e/tests/fixtures/test-sheet.xlsx';
|
|||||||
test('sheet file upload', async ({ page }) => {
|
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 all' }).click();
|
||||||
await page.getByRole('button', { name: 'Delete all' }).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();
|
||||||
|
|||||||
Reference in New Issue
Block a user