From 8196ea584dfe5bcd2988c0da8aa512659751b3ee Mon Sep 17 00:00:00 2001 From: Carlos Valente <34649812+cpvalente@users.noreply.github.com> Date: Sun, 3 Mar 2024 20:42:36 +0100 Subject: [PATCH] UI tweaks (#800) * style: placeholder for progress value * style: rundown menu * style: extracted rundown takes whole screen * style: tweaks to rundown indicators * feat: allow exporting info * style: indicate action --- apps/client/src/AppRouter.tsx | 9 +++ apps/client/src/common/stores/appModeStore.ts | 1 + .../app-settings/panel/Panel.module.scss | 1 + .../panel/log-panel/LogExport.module.scss | 3 + .../panel/log-panel/LogExport.tsx | 35 ++++++++++++ .../app-settings/panel/log-panel/LogPanel.tsx | 17 ++---- .../panel/log-panel => log}/Log.module.scss | 5 +- .../panel/log-panel => log}/Log.tsx | 28 +++++----- apps/client/src/features/menu/MenuBar.tsx | 44 +-------------- .../src/features/menu/RundownMenu.module.scss | 4 -- .../client/src/features/overview/Overview.tsx | 2 +- .../rundown/RundownExport.module.scss | 11 ++++ .../src/features/rundown/RundownExport.tsx | 5 +- .../src/features/rundown/RundownWrapper.tsx | 2 + .../event-block/EventBlock.module.scss | 2 +- .../rundown/event-block/EventBlockInner.tsx | 9 ++- .../event-block/RundownIndicators.module.scss | 7 ++- .../rundown-header/RundownHeader.module.scss | 8 +++ .../rundown/rundown-header/RundownHeader.tsx | 56 +++++++++++++++++++ .../rundown-header}/RundownMenu.tsx | 4 +- 20 files changed, 166 insertions(+), 87 deletions(-) create mode 100644 apps/client/src/features/app-settings/panel/log-panel/LogExport.module.scss create mode 100644 apps/client/src/features/app-settings/panel/log-panel/LogExport.tsx rename apps/client/src/features/{app-settings/panel/log-panel => log}/Log.module.scss (89%) rename apps/client/src/features/{app-settings/panel/log-panel => log}/Log.tsx (84%) delete mode 100644 apps/client/src/features/menu/RundownMenu.module.scss create mode 100644 apps/client/src/features/rundown/rundown-header/RundownHeader.module.scss create mode 100644 apps/client/src/features/rundown/rundown-header/RundownHeader.tsx rename apps/client/src/features/{menu => rundown/rundown-header}/RundownMenu.tsx (93%) diff --git a/apps/client/src/AppRouter.tsx b/apps/client/src/AppRouter.tsx index eef3495b1..6fe048cc0 100644 --- a/apps/client/src/AppRouter.tsx +++ b/apps/client/src/AppRouter.tsx @@ -2,6 +2,7 @@ import { lazy, Suspense } from 'react'; import { Navigate, Route, Routes } from 'react-router-dom'; import withAlias from './features/AliasWrapper'; +import Log from './features/log/Log'; import withData from './features/viewers/ViewWrapper'; const Editor = lazy(() => import('./features/editors/ProtectedEditor')); @@ -84,6 +85,14 @@ export default function AppRouter() { } /> + + + + } + /> {/*/!* Send to default if nothing found *!/*/} } /> diff --git a/apps/client/src/common/stores/appModeStore.ts b/apps/client/src/common/stores/appModeStore.ts index 699b75456..5e675ba05 100644 --- a/apps/client/src/common/stores/appModeStore.ts +++ b/apps/client/src/common/stores/appModeStore.ts @@ -3,6 +3,7 @@ import { create } from 'zustand'; export enum AppMode { Run = 'run', Edit = 'edit', + Freeze = 'freeze', } const appModeKey = 'ontime-app-mode'; diff --git a/apps/client/src/features/app-settings/panel/Panel.module.scss b/apps/client/src/features/app-settings/panel/Panel.module.scss index 84314ebf4..421540bf0 100644 --- a/apps/client/src/features/app-settings/panel/Panel.module.scss +++ b/apps/client/src/features/app-settings/panel/Panel.module.scss @@ -34,6 +34,7 @@ $inner-padding: 1rem; display: flex; flex-direction: column; gap: 1rem; + color: $ui-white; } .paragraph { diff --git a/apps/client/src/features/app-settings/panel/log-panel/LogExport.module.scss b/apps/client/src/features/app-settings/panel/log-panel/LogExport.module.scss new file mode 100644 index 000000000..93c66f6b4 --- /dev/null +++ b/apps/client/src/features/app-settings/panel/log-panel/LogExport.module.scss @@ -0,0 +1,3 @@ +.iconRotate { + transform: rotate(45deg); +} diff --git a/apps/client/src/features/app-settings/panel/log-panel/LogExport.tsx b/apps/client/src/features/app-settings/panel/log-panel/LogExport.tsx new file mode 100644 index 000000000..094f1f6f6 --- /dev/null +++ b/apps/client/src/features/app-settings/panel/log-panel/LogExport.tsx @@ -0,0 +1,35 @@ +import { MouseEvent } from 'react'; +import { Button } from '@chakra-ui/react'; +import { IoArrowUp } from '@react-icons/all-files/io5/IoArrowUp'; + +import { handleLinks } from '../../../../common/utils/linkUtils'; +import Log from '../../../log/Log'; +import * as Panel from '../PanelUtils'; + +import style from './LogExport.module.scss'; + +export default function LogExport() { + const extract = (event: MouseEvent) => { + handleLinks(event, 'log'); + }; + + return ( + + + + Network log + + + + + + + ); +} diff --git a/apps/client/src/features/app-settings/panel/log-panel/LogPanel.tsx b/apps/client/src/features/app-settings/panel/log-panel/LogPanel.tsx index 0f53582da..0f3281a69 100644 --- a/apps/client/src/features/app-settings/panel/log-panel/LogPanel.tsx +++ b/apps/client/src/features/app-settings/panel/log-panel/LogPanel.tsx @@ -1,6 +1,6 @@ import * as Panel from '../PanelUtils'; -import Log from './Log'; +import LogExport from './LogExport'; import InfoNif from './NetworkInterfaces'; export default function LogPanel() { @@ -8,19 +8,10 @@ export default function LogPanel() { <> Application log - Available networks - - Ontime is streaming on the following network interfaces - - - - - - Network log - - - + Ontime is streaming on the following network interfaces + + ); } diff --git a/apps/client/src/features/app-settings/panel/log-panel/Log.module.scss b/apps/client/src/features/log/Log.module.scss similarity index 89% rename from apps/client/src/features/app-settings/panel/log-panel/Log.module.scss rename to apps/client/src/features/log/Log.module.scss index bd2b0025e..08dec28f5 100644 --- a/apps/client/src/features/app-settings/panel/log-panel/Log.module.scss +++ b/apps/client/src/features/log/Log.module.scss @@ -5,7 +5,7 @@ $info-hover: $section-white; font-size: $inner-section-text-size; overflow-y: auto; user-select: text; - min-height: 10vh; + min-height: 20vh; max-height: 40vh; } @@ -44,7 +44,6 @@ $info-hover: $section-white; .buttonBar { display: flex; flex-wrap: wrap; - gap: 0.5rem; - justify-content: flex-start; + gap: 1em; padding-bottom: 0.5rem; } diff --git a/apps/client/src/features/app-settings/panel/log-panel/Log.tsx b/apps/client/src/features/log/Log.tsx similarity index 84% rename from apps/client/src/features/app-settings/panel/log-panel/Log.tsx rename to apps/client/src/features/log/Log.tsx index d6f014c86..12dd3ad19 100644 --- a/apps/client/src/features/app-settings/panel/log-panel/Log.tsx +++ b/apps/client/src/features/log/Log.tsx @@ -2,7 +2,7 @@ import { useCallback, useState } from 'react'; import { Button } from '@chakra-ui/react'; import { LogOrigin } from 'ontime-types'; -import { clearLogs, useLogData } from '../../../../common/stores/logger'; +import { clearLogs, useLogData } from '../../common/stores/logger'; import style from './Log.module.scss'; @@ -51,8 +51,8 @@ export default function Log() { <>
-
diff --git a/apps/client/src/features/menu/MenuBar.tsx b/apps/client/src/features/menu/MenuBar.tsx index b1744f72a..3a1f96754 100644 --- a/apps/client/src/features/menu/MenuBar.tsx +++ b/apps/client/src/features/menu/MenuBar.tsx @@ -1,19 +1,11 @@ import { memo, useCallback, useEffect } from 'react'; -import { IconButton, MenuButton, Tooltip } from '@chakra-ui/react'; -import { IoAdd } from '@react-icons/all-files/io5/IoAdd'; -import { IoOptions } from '@react-icons/all-files/io5/IoOptions'; -import { IoPlay } from '@react-icons/all-files/io5/IoPlay'; import { IoSettingsOutline } from '@react-icons/all-files/io5/IoSettingsOutline'; -import { IoSnowOutline } from '@react-icons/all-files/io5/IoSnowOutline'; import QuitIconBtn from '../../common/components/buttons/QuitIconBtn'; import TooltipActionBtn from '../../common/components/buttons/TooltipActionBtn'; import useElectronEvent from '../../common/hooks/useElectronEvent'; -import { AppMode, useAppMode } from '../../common/stores/appModeStore'; import { cx } from '../../common/utils/styleUtils'; -import RundownMenu from './RundownMenu'; - import style from './MenuBar.module.scss'; interface MenuBarProps { @@ -40,11 +32,6 @@ const MenuBar = (props: MenuBarProps) => { const { isOldSettingsOpen, onSettingsOpen, onSettingsClose, openSettings, isSettingsOpen } = props; const { isElectron, sendToElectron } = useElectronEvent(); - const appMode = useAppMode((state) => state.mode); - const setAppMode = useAppMode((state) => state.setMode); - - const setRunMode = () => setAppMode(AppMode.Run); - const setEditMode = () => setAppMode(AppMode.Edit); const sendShutdown = () => { if (isElectron) { sendToElectron('shutdown', 'now'); @@ -84,39 +71,10 @@ const MenuBar = (props: MenuBarProps) => {
- - - } {...buttonStyle} aria-label='Rundown menu' /> - - - } - className={appMode === AppMode.Run ? style.open : ''} - clickHandler={setRunMode} - tooltip='Freeze rundown' - aria-label='Freeze rundown' - /> - } - className={appMode === AppMode.Run ? style.open : ''} - clickHandler={setRunMode} - tooltip='Run mode' - aria-label='Run mode' - /> - } - className={appMode === AppMode.Edit ? style.open : ''} - clickHandler={setEditMode} - tooltip='Edit mode' - aria-label='Edit mode' - /> +
} className={isOldSettingsOpen ? style.open : ''} clickHandler={onSettingsOpen} diff --git a/apps/client/src/features/menu/RundownMenu.module.scss b/apps/client/src/features/menu/RundownMenu.module.scss deleted file mode 100644 index 19c3467dc..000000000 --- a/apps/client/src/features/menu/RundownMenu.module.scss +++ /dev/null @@ -1,4 +0,0 @@ -.headerButtons { - text-align: right; - padding: 1.5rem 1rem 0 1rem; -} diff --git a/apps/client/src/features/overview/Overview.tsx b/apps/client/src/features/overview/Overview.tsx index c9d14f4d0..1ce3047a8 100644 --- a/apps/client/src/features/overview/Overview.tsx +++ b/apps/client/src/features/overview/Overview.tsx @@ -56,7 +56,7 @@ function RuntimeOverview() { const current = selectedEventIndex !== null ? selectedEventIndex + 1 : enDash; const ofTotal = numEvents || enDash; - const progressText = numEvents ? `${current} of ${ofTotal}` : ''; + const progressText = numEvents ? `${current} of ${ofTotal}` : '-'; const isAhead = offset <= 0; let offsetText = millisToString(Math.abs(offset), { fallback: enDash }); diff --git a/apps/client/src/features/rundown/RundownExport.module.scss b/apps/client/src/features/rundown/RundownExport.module.scss index f6de36b78..d2f5e3964 100644 --- a/apps/client/src/features/rundown/RundownExport.module.scss +++ b/apps/client/src/features/rundown/RundownExport.module.scss @@ -3,6 +3,17 @@ .rundownExport { height: 100%; flex: 1; + + &.extracted { + .list { + flex: 1; + max-width: none; + } + .side { + flex: 1; + max-width: none; + } + } } .rundown { diff --git a/apps/client/src/features/rundown/RundownExport.tsx b/apps/client/src/features/rundown/RundownExport.tsx index a9d7c5dc1..acd8acdb4 100644 --- a/apps/client/src/features/rundown/RundownExport.tsx +++ b/apps/client/src/features/rundown/RundownExport.tsx @@ -3,6 +3,7 @@ import { IoArrowUp } from '@react-icons/all-files/io5/IoArrowUp'; import ErrorBoundary from '../../common/components/error-boundary/ErrorBoundary'; import { handleLinks } from '../../common/utils/linkUtils'; +import { cx } from '../../common/utils/styleUtils'; import EventEditor from './event-editor/EventEditor'; import RundownWrapper from './RundownWrapper'; @@ -12,8 +13,10 @@ import style from './RundownExport.module.scss'; const RundownExport = () => { const isExtracted = window.location.pathname.includes('/rundown'); + const classes = cx([style.rundownExport, isExtracted && style.extracted]); + return ( -
+
diff --git a/apps/client/src/features/rundown/RundownWrapper.tsx b/apps/client/src/features/rundown/RundownWrapper.tsx index 8a9971271..d79ffd77c 100644 --- a/apps/client/src/features/rundown/RundownWrapper.tsx +++ b/apps/client/src/features/rundown/RundownWrapper.tsx @@ -1,6 +1,7 @@ import Empty from '../../common/components/state/Empty'; import useRundown from '../../common/hooks-query/useRundown'; +import RundownHeader from './rundown-header/RundownHeader'; import Rundown from './Rundown'; import styles from './Rundown.module.scss'; @@ -10,6 +11,7 @@ export default function RundownWrapper() { return (
+ {status === 'success' && data ? : }
); diff --git a/apps/client/src/features/rundown/event-block/EventBlock.module.scss b/apps/client/src/features/rundown/event-block/EventBlock.module.scss index eebc35431..277aa2bf1 100644 --- a/apps/client/src/features/rundown/event-block/EventBlock.module.scss +++ b/apps/client/src/features/rundown/event-block/EventBlock.module.scss @@ -14,7 +14,7 @@ $skip-opacity: 0.1; 'binder pb-actions estatus estatus' 'binder ... ... ...'; - grid-template-columns: $block-binder-width auto 1fr auto; + grid-template-columns: $block-binder-width 3rem 1fr auto; grid-template-rows: 0.25rem 2.25rem 2.25rem 2.25rem 0.25rem; align-items: center; padding-right: $block-clearance; diff --git a/apps/client/src/features/rundown/event-block/EventBlockInner.tsx b/apps/client/src/features/rundown/event-block/EventBlockInner.tsx index 69fb7446c..fb7f766c1 100644 --- a/apps/client/src/features/rundown/event-block/EventBlockInner.tsx +++ b/apps/client/src/features/rundown/event-block/EventBlockInner.tsx @@ -11,6 +11,7 @@ import { IoStop } from '@react-icons/all-files/io5/IoStop'; import { IoTime } from '@react-icons/all-files/io5/IoTime'; import { EndAction, MaybeString, Playback, TimerType, TimeStrategy } from 'ontime-types'; +import { cx } from '../../../common/utils/styleUtils'; import { tooltipDelayMid } from '../../../ontimeConfig'; import EditableBlockTitle from '../common/EditableBlockTitle'; import { EventItemActions } from '../RundownEntry'; @@ -147,14 +148,16 @@ export default memo(EventBlockInner); function EndActionIcon(props: { action: EndAction; className: string }) { const { action, className } = props; + const maybeActiveClasses = cx([action !== EndAction.None && style.active, className]); + if (action === EndAction.LoadNext) { - return ; + return ; } if (action === EndAction.PlayNext) { - return ; + return ; } if (action === EndAction.Stop) { - return ; + return ; } return ; } diff --git a/apps/client/src/features/rundown/event-block/RundownIndicators.module.scss b/apps/client/src/features/rundown/event-block/RundownIndicators.module.scss index 44a2da0a9..55bd51c07 100644 --- a/apps/client/src/features/rundown/event-block/RundownIndicators.module.scss +++ b/apps/client/src/features/rundown/event-block/RundownIndicators.module.scss @@ -1,10 +1,12 @@ +/** binder + gap + pb-actions */ +$gap-left: calc(2rem + 0.25rem + 3rem); + .indicators { font-size: calc(1rem - 5px); position: absolute; top: -1em; z-index: 2; - margin: 0 20%; - width: 60%; + margin-left: $gap-left; display: flex; gap: 0.5rem; @@ -14,6 +16,7 @@ padding: 0 0.5rem; border-radius: 2px; background-color: $bg-colour; + color: $ui-black; } .delay { diff --git a/apps/client/src/features/rundown/rundown-header/RundownHeader.module.scss b/apps/client/src/features/rundown/rundown-header/RundownHeader.module.scss new file mode 100644 index 000000000..6c297ad58 --- /dev/null +++ b/apps/client/src/features/rundown/rundown-header/RundownHeader.module.scss @@ -0,0 +1,8 @@ +.header { + padding-left: 2rem; + padding-right: 1rem; + + display: flex; + align-items: center; + justify-content: space-between; +} diff --git a/apps/client/src/features/rundown/rundown-header/RundownHeader.tsx b/apps/client/src/features/rundown/rundown-header/RundownHeader.tsx new file mode 100644 index 000000000..b370e18f9 --- /dev/null +++ b/apps/client/src/features/rundown/rundown-header/RundownHeader.tsx @@ -0,0 +1,56 @@ +import { Button, ButtonGroup, MenuButton } from '@chakra-ui/react'; +import { IoAdd } from '@react-icons/all-files/io5/IoAdd'; +import { IoOptions } from '@react-icons/all-files/io5/IoOptions'; +import { IoPlay } from '@react-icons/all-files/io5/IoPlay'; +import { IoSnowOutline } from '@react-icons/all-files/io5/IoSnowOutline'; + +import TooltipActionBtn from '../../../common/components/buttons/TooltipActionBtn'; +import { AppMode, useAppMode } from '../../../common/stores/appModeStore'; + +import RundownMenu from './RundownMenu'; + +import style from './RundownHeader.module.scss'; + +export default function RundownHeader() { + const appMode = useAppMode((state) => state.mode); + const setAppMode = useAppMode((state) => state.setMode); + const setRunMode = () => setAppMode(AppMode.Run); + const setEditMode = () => setAppMode(AppMode.Edit); + const setFreezeMode = () => setAppMode(AppMode.Freeze); + + return ( +
+ + } + clickHandler={setFreezeMode} + tooltip='Freeze rundown' + aria-label='Freeze rundown' + /> + } + clickHandler={setRunMode} + tooltip='Run mode' + aria-label='Run mode' + /> + } + clickHandler={setEditMode} + tooltip='Edit mode' + aria-label='Edit mode' + /> + + + } aria-label='Rundown menu' variant='ontime-ghosted'> + Rundown + + +
+ ); +} diff --git a/apps/client/src/features/menu/RundownMenu.tsx b/apps/client/src/features/rundown/rundown-header/RundownMenu.tsx similarity index 93% rename from apps/client/src/features/menu/RundownMenu.tsx rename to apps/client/src/features/rundown/rundown-header/RundownMenu.tsx index b1bf937e1..cdc556f00 100644 --- a/apps/client/src/features/menu/RundownMenu.tsx +++ b/apps/client/src/features/rundown/rundown-header/RundownMenu.tsx @@ -6,8 +6,8 @@ import { IoTimerOutline } from '@react-icons/all-files/io5/IoTimerOutline'; import { IoTrashOutline } from '@react-icons/all-files/io5/IoTrashOutline'; import { SupportedEvent } from 'ontime-types'; -import { useEventAction } from '../../common/hooks/useEventAction'; -import { useEventSelection } from '../rundown/useEventSelection'; +import { useEventAction } from '../../../common/hooks/useEventAction'; +import { useEventSelection } from '../useEventSelection'; const RundownMenu = ({ children }: { children: ReactNode }) => { const { clearSelectedEvents } = useEventSelection();