From 5600235ba172b8eee805885afdab979f052d7c4d Mon Sep 17 00:00:00 2001 From: Carlos Valente Date: Fri, 4 Jul 2025 12:13:06 +0200 Subject: [PATCH] refactor: restructure settings refactor: migrate react components --- .../buttons/BaseButtonStyles.module.scss | 23 ++- .../src/common/components/buttons/Button.tsx | 10 +- .../common/components/buttons/IconButton.tsx | 10 +- .../common/components/info/Info.module.scss | 22 ++- .../src/common/components/info/Info.tsx | 13 +- .../navigation-menu/ViewNavigationMenu.tsx | 13 +- .../components/playback-icon/PlaybackIcon.tsx | 40 ----- .../src/features/app-settings/AppSettings.tsx | 12 +- .../app-settings/panel-list/PanelList.tsx | 4 +- .../panel-utils/PanelUtils.module.scss | 1 + .../app-settings/panel-utils/PanelUtils.tsx | 12 +- .../automations-panel/AutomationForm.tsx | 127 ++++---------- .../AutomationSettingsForm.tsx | 20 +-- .../automations-panel/AutomationsList.tsx | 28 ++- .../automations-panel/OntimeActionForm.tsx | 15 +- .../panel/automations-panel/TriggerForm.tsx | 12 +- .../panel/automations-panel/TriggersList.tsx | 15 +- .../automations-panel/TriggersListItem.tsx | 24 +-- .../template-input/TemplateInput.tsx | 4 +- .../feature-panel/FeaturePanel.module.scss | 11 ++ .../panel/feature-panel/FeaturePanel.tsx | 42 +++++ .../GenerateLinkForm.module.scss | 0 .../GenerateLinkForm.tsx | 0 .../GenerateLinkFormExport.tsx | 0 .../ReportSettings.module.scss | 0 .../ReportSettings.tsx | 21 +-- .../UrlPresetsForm.tsx | 32 ++-- .../reportSettings.utils.ts | 0 .../FeatureSettingsPanel.tsx | 30 ---- .../panel/general-panel/GeneralPanel.tsx | 28 --- .../CustomFields.tsx | 30 ++-- .../ManagePanel.module.scss} | 12 +- .../panel/manage-panel/ManagePanel.tsx | 33 ++++ .../ManageRundowns.tsx | 2 +- .../RundownDefaultSettings.tsx} | 44 +---- .../composite}/CustomFieldEntry.tsx | 26 +-- .../composite}/CustomFieldForm.tsx | 16 +- .../sources-panel/GSheetInfo.tsx | 4 +- .../sources-panel/GSheetSetup.tsx | 55 ++---- .../sources-panel/ImportReview.tsx | 8 +- .../sources-panel/SourcesPanel.module.scss | 0 .../sources-panel/SourcesPanel.tsx | 161 ++++++++---------- .../import-map/ImportMapForm.tsx | 50 +++--- .../__test__/importMapUtils.test.ts | 0 .../import-map/importMapUtils.ts | 0 .../preview/PreviewRundown.module.scss | 0 .../sources-panel/preview/PreviewRundown.tsx | 6 +- .../sources-panel/useGoogleSheet.ts | 8 +- .../sources-panel/useSheetStore.ts | 0 .../panel/network-panel/NetworkLogPanel.tsx | 22 +-- .../ClientControlPanel.module.scss | 0 .../client-control}/ClientControlPanel.tsx | 2 +- .../client-control}/ClientList.tsx | 51 +++--- .../panel/project-panel/ProjectForm.tsx | 14 +- .../panel/project-panel/ProjectList.tsx | 68 +++++--- .../panel/project-panel/ProjectMergeForm.tsx | 13 +- .../project-panel/ProjectPanel.module.scss | 37 +--- .../panel/project-panel/ProjectPanel.tsx | 10 -- .../GeneralSettings.tsx} | 25 +-- .../ProjectData.tsx | 2 +- .../settings-panel/SettingsPanel.module.scss | 33 ++++ .../panel/settings-panel/SettingsPanel.tsx | 28 +++ .../ViewSettings.tsx} | 53 ++---- .../composite}/GeneralPinInput.tsx | 2 +- .../composite}/StyleEditor.module.scss | 0 .../composite}/StyleEditor.tsx | 0 .../composite}/StyleEditorModal.module.scss | 0 .../composite}/StyleEditorModal.tsx | 10 +- .../composite}/prismjs.d.ts | 0 .../panel/shutdown-panel/ShutdownPanel.tsx | 60 +++---- .../app-settings/useAppSettingsMenu.tsx | 60 +++---- .../src/features/control/message/InputRow.tsx | 12 +- .../operator/edit-modal/EditModal.tsx | 5 +- apps/client/src/features/rundown/Rundown.tsx | 4 +- .../rundown/common/EditableBlockTitle.tsx | 11 +- .../rundown/placements/FinderPlacement.tsx | 11 +- .../rundown/quick-add-block/QuickAddBlock.tsx | 4 +- .../rundown-block/RundownBlock.module.scss | 1 + .../rundown/rundown-block/RundownBlock.tsx | 10 +- .../rundown/rundown-delay/RundownDelay.tsx | 9 +- .../cuesheet-table-elements/BlockRow.tsx | 2 +- .../cuesheet-table-elements/DelayRow.tsx | 1 + .../cuesheet-table-elements/EventRow.tsx | 1 + .../CuesheetShareModal.tsx | 2 +- apps/client/src/views/editor/Editor.tsx | 9 +- .../src/views/editor/welcome/Welcome.tsx | 2 +- .../welcome/composite/ImportProjectButton.tsx | 3 +- ....parser.ts => viewSettings.parser.test.ts} | 0 ...message.utils.ts => message.utils.test.ts} | 0 .../services/rundown-service/rundownCache.ts | 0 e2e/tests/000-upload-showfile.spec.ts | 8 +- e2e/tests/features/202-cuesheet.spec.ts | 4 +- e2e/tests/features/206-url-preset.spec.ts | 4 +- 93 files changed, 711 insertions(+), 906 deletions(-) delete mode 100644 apps/client/src/common/components/playback-icon/PlaybackIcon.tsx create mode 100644 apps/client/src/features/app-settings/panel/feature-panel/FeaturePanel.module.scss create mode 100644 apps/client/src/features/app-settings/panel/feature-panel/FeaturePanel.tsx rename apps/client/src/features/app-settings/panel/{network-panel => feature-panel}/GenerateLinkForm.module.scss (100%) rename apps/client/src/features/app-settings/panel/{network-panel => feature-panel}/GenerateLinkForm.tsx (100%) rename apps/client/src/features/app-settings/panel/{network-panel => feature-panel}/GenerateLinkFormExport.tsx (100%) rename apps/client/src/features/app-settings/panel/{feature-settings-panel => feature-panel}/ReportSettings.module.scss (100%) rename apps/client/src/features/app-settings/panel/{feature-settings-panel => feature-panel}/ReportSettings.tsx (85%) rename apps/client/src/features/app-settings/panel/{feature-settings-panel => feature-panel}/UrlPresetsForm.tsx (89%) rename apps/client/src/features/app-settings/panel/{feature-settings-panel => feature-panel}/reportSettings.utils.ts (100%) delete mode 100644 apps/client/src/features/app-settings/panel/feature-settings-panel/FeatureSettingsPanel.tsx delete mode 100644 apps/client/src/features/app-settings/panel/general-panel/GeneralPanel.tsx rename apps/client/src/features/app-settings/panel/{feature-settings-panel/custom-fields => manage-panel}/CustomFields.tsx (70%) rename apps/client/src/features/app-settings/panel/{feature-settings-panel/FeatureSettings.module.scss => manage-panel/ManagePanel.module.scss} (79%) create mode 100644 apps/client/src/features/app-settings/panel/manage-panel/ManagePanel.tsx rename apps/client/src/features/app-settings/panel/{project-panel => manage-panel}/ManageRundowns.tsx (98%) rename apps/client/src/features/app-settings/panel/{interface-panel/EditorSettingsForm.tsx => manage-panel/RundownDefaultSettings.tsx} (74%) rename apps/client/src/features/app-settings/panel/{feature-settings-panel/custom-fields => manage-panel/composite}/CustomFieldEntry.tsx (76%) rename apps/client/src/features/app-settings/panel/{feature-settings-panel/custom-fields => manage-panel/composite}/CustomFieldForm.tsx (90%) rename apps/client/src/features/app-settings/panel/{ => manage-panel}/sources-panel/GSheetInfo.tsx (78%) rename apps/client/src/features/app-settings/panel/{ => manage-panel}/sources-panel/GSheetSetup.tsx (77%) rename apps/client/src/features/app-settings/panel/{ => manage-panel}/sources-panel/ImportReview.tsx (81%) rename apps/client/src/features/app-settings/panel/{ => manage-panel}/sources-panel/SourcesPanel.module.scss (100%) rename apps/client/src/features/app-settings/panel/{ => manage-panel}/sources-panel/SourcesPanel.tsx (61%) rename apps/client/src/features/app-settings/panel/{ => manage-panel}/sources-panel/import-map/ImportMapForm.tsx (84%) rename apps/client/src/features/app-settings/panel/{ => manage-panel}/sources-panel/import-map/__test__/importMapUtils.test.ts (100%) rename apps/client/src/features/app-settings/panel/{ => manage-panel}/sources-panel/import-map/importMapUtils.ts (100%) rename apps/client/src/features/app-settings/panel/{ => manage-panel}/sources-panel/preview/PreviewRundown.module.scss (100%) rename apps/client/src/features/app-settings/panel/{ => manage-panel}/sources-panel/preview/PreviewRundown.tsx (95%) rename apps/client/src/features/app-settings/panel/{ => manage-panel}/sources-panel/useGoogleSheet.ts (92%) rename apps/client/src/features/app-settings/panel/{ => manage-panel}/sources-panel/useSheetStore.ts (100%) rename apps/client/src/features/app-settings/panel/{client-control-panel => network-panel/client-control}/ClientControlPanel.module.scss (100%) rename apps/client/src/features/app-settings/panel/{client-control-panel => network-panel/client-control}/ClientControlPanel.tsx (83%) rename apps/client/src/features/app-settings/panel/{client-control-panel => network-panel/client-control}/ClientList.tsx (72%) rename apps/client/src/features/app-settings/panel/{general-panel/GeneralPanelForm.tsx => settings-panel/GeneralSettings.tsx} (89%) rename apps/client/src/features/app-settings/panel/{project-panel => settings-panel}/ProjectData.tsx (99%) create mode 100644 apps/client/src/features/app-settings/panel/settings-panel/SettingsPanel.module.scss create mode 100644 apps/client/src/features/app-settings/panel/settings-panel/SettingsPanel.tsx rename apps/client/src/features/app-settings/panel/{general-panel/ViewSettingsForm.tsx => settings-panel/ViewSettings.tsx} (73%) rename apps/client/src/features/app-settings/panel/{general-panel => settings-panel/composite}/GeneralPinInput.tsx (95%) rename apps/client/src/features/app-settings/panel/{general-panel => settings-panel/composite}/StyleEditor.module.scss (100%) rename apps/client/src/features/app-settings/panel/{general-panel => settings-panel/composite}/StyleEditor.tsx (100%) rename apps/client/src/features/app-settings/panel/{general-panel => settings-panel/composite}/StyleEditorModal.module.scss (100%) rename apps/client/src/features/app-settings/panel/{general-panel => settings-panel/composite}/StyleEditorModal.tsx (91%) rename apps/client/src/features/app-settings/panel/{general-panel => settings-panel/composite}/prismjs.d.ts (100%) rename apps/server/src/api-data/view-settings/__tests__/{viewSettings.parser.ts => viewSettings.parser.test.ts} (100%) rename apps/server/src/services/message-service/__tests__/{message.utils.ts => message.utils.test.ts} (100%) delete mode 100644 apps/server/src/services/rundown-service/rundownCache.ts diff --git a/apps/client/src/common/components/buttons/BaseButtonStyles.module.scss b/apps/client/src/common/components/buttons/BaseButtonStyles.module.scss index ac0be6ef4..0466b499c 100644 --- a/apps/client/src/common/components/buttons/BaseButtonStyles.module.scss +++ b/apps/client/src/common/components/buttons/BaseButtonStyles.module.scss @@ -1,6 +1,7 @@ .subtle { background: $gray-1050; color: $blue-400; + line-height: 1em; &:hover:not(:disabled):not(:active) { background: $gray-1000; @@ -116,4 +117,24 @@ &:disabled { opacity: $opacity-disabled; } -} \ No newline at end of file +} + + +.ghosted-destructive { + background: transparent; + color: $red-500; + + &:hover:not(:disabled):not(:active) { + background: $gray-1000; + color: $red-500; + } + + &:active:not(:disabled) { + background: $gray-1100; + border-color: $gray-1250; + } + + &:disabled { + opacity: $opacity-disabled; + } +} diff --git a/apps/client/src/common/components/buttons/Button.tsx b/apps/client/src/common/components/buttons/Button.tsx index a23c29319..9457e74f4 100644 --- a/apps/client/src/common/components/buttons/Button.tsx +++ b/apps/client/src/common/components/buttons/Button.tsx @@ -6,7 +6,15 @@ import { cx } from '../../utils/styleUtils'; import style from './Button.module.scss'; interface ButtonProps extends ButtonHTMLAttributes { - variant?: 'primary' | 'subtle' | 'subtle-white' | 'destructive' | 'subtle-destructive' | 'ghosted' | 'ghosted-white'; + variant?: + | 'primary' + | 'subtle' + | 'subtle-white' + | 'destructive' + | 'subtle-destructive' + | 'ghosted' + | 'ghosted-white' + | 'ghosted-destructive'; size?: 'small' | 'medium' | 'large' | 'xlarge'; fluid?: boolean; loading?: boolean; diff --git a/apps/client/src/common/components/buttons/IconButton.tsx b/apps/client/src/common/components/buttons/IconButton.tsx index 6492b6d3b..0fe1e26b5 100644 --- a/apps/client/src/common/components/buttons/IconButton.tsx +++ b/apps/client/src/common/components/buttons/IconButton.tsx @@ -5,7 +5,15 @@ import { cx } from '../../utils/styleUtils'; import style from './IconButton.module.scss'; interface IconButtonProps extends ButtonHTMLAttributes { - variant?: 'primary' | 'subtle' | 'subtle-white' | 'destructive' | 'subtle-destructive' | 'ghosted' | 'ghosted-white'; + variant?: + | 'primary' + | 'subtle' + | 'subtle-white' + | 'destructive' + | 'subtle-destructive' + | 'ghosted' + | 'ghosted-white' + | 'ghosted-destructive'; size?: 'small' | 'medium' | 'large' | 'xlarge'; } diff --git a/apps/client/src/common/components/info/Info.module.scss b/apps/client/src/common/components/info/Info.module.scss index 8cbe2774d..3939cbb54 100644 --- a/apps/client/src/common/components/info/Info.module.scss +++ b/apps/client/src/common/components/info/Info.module.scss @@ -7,15 +7,29 @@ border-radius: 3px; font-size: $text-body-size; padding: 1rem; - - .content { - color: $gray-200; - } + color: $gray-200; svg { min-width: 1.5rem; align-self: start; font-size: 1.5rem; + } +} + +.info { + svg { color: $info-blue; } } + +.warning { + svg { + color: $orange-500; + } +} + +.error { + svg { + color: $red-500; + } +} diff --git a/apps/client/src/common/components/info/Info.tsx b/apps/client/src/common/components/info/Info.tsx index bb374182a..8153da6cc 100644 --- a/apps/client/src/common/components/info/Info.tsx +++ b/apps/client/src/common/components/info/Info.tsx @@ -1,5 +1,5 @@ import { PropsWithChildren } from 'react'; -import { IoAlertCircle } from 'react-icons/io5'; +import { IoAlertCircle, IoWarning } from 'react-icons/io5'; import { cx } from '../../utils/styleUtils'; @@ -7,14 +7,15 @@ import style from './Info.module.scss'; interface InfoProps { className?: string; + type?: 'info' | 'warning' | 'error'; } -export default function Info(props: PropsWithChildren) { - const { className, children } = props; - +export default function Info({ className, type = 'info', children }: PropsWithChildren) { return ( -
- +
+ {type === 'info' && } + {type === 'warning' && } + {type === 'error' && }
{children}
); diff --git a/apps/client/src/common/components/navigation-menu/ViewNavigationMenu.tsx b/apps/client/src/common/components/navigation-menu/ViewNavigationMenu.tsx index f1efead2a..0b36187f1 100644 --- a/apps/client/src/common/components/navigation-menu/ViewNavigationMenu.tsx +++ b/apps/client/src/common/components/navigation-menu/ViewNavigationMenu.tsx @@ -1,6 +1,5 @@ import { memo } from 'react'; -import { useDisclosure } from '@chakra-ui/react'; -import { useHotkeys } from '@mantine/hooks'; +import { useDisclosure, useHotkeys } from '@mantine/hooks'; import FloatingNavigation from './floating-navigation/FloatingNavigation'; import ViewLockedIcon from './view-locked-icon/ViewLockedIcon'; @@ -14,17 +13,15 @@ interface ViewNavigationMenuProps { export default memo(ViewNavigationMenu); function ViewNavigationMenu({ isLockable, supressSettings }: ViewNavigationMenuProps) { - const { isOpen: isMenuOpen, onOpen: onMenuOpen, onClose: onMenuClose } = useDisclosure(); + const [isMenuOpen, menuHandler] = useDisclosure(); const { showEditFormDrawer, isViewLocked } = useViewEditor({ isLockable }); - const toggleMenu = () => (isMenuOpen ? onMenuClose() : onMenuOpen()); - useHotkeys([ [ 'Space', () => { if (isViewLocked) return; - toggleMenu(); + menuHandler.toggle(); }, { preventDefault: true }, ], @@ -45,10 +42,10 @@ function ViewNavigationMenu({ isLockable, supressSettings }: ViewNavigationMenuP return ( <> showEditFormDrawer()} /> - + ); } diff --git a/apps/client/src/common/components/playback-icon/PlaybackIcon.tsx b/apps/client/src/common/components/playback-icon/PlaybackIcon.tsx deleted file mode 100644 index 0780cfe39..000000000 --- a/apps/client/src/common/components/playback-icon/PlaybackIcon.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import { IoPause, IoPlay, IoStop } from 'react-icons/io5'; -import { Tooltip } from '@chakra-ui/react'; -import { Playback } from 'ontime-types'; - -import { tooltipDelayFast } from '../../../ontimeConfig'; - -interface PlaybackIconProps { - state: Playback; - skipTooltip?: boolean; - className?: string; -} - -export default function PlaybackIcon(props: PlaybackIconProps) { - const { state, skipTooltip, className } = props; - - // if timer is Pause or Armed - let label = 'Timer Paused'; - let Icon = IoPause; - - if (state === Playback.Roll) { - label = 'Timer Rolling'; - Icon = IoPlay; - } else if (state === Playback.Play) { - label = 'Timer Playing'; - Icon = IoPlay; - } else if (state === Playback.Stop) { - label = 'Timer Stopped'; - Icon = IoStop; - } - - if (skipTooltip) { - return ; - } - - return ( - - - - ); -} diff --git a/apps/client/src/features/app-settings/AppSettings.tsx b/apps/client/src/features/app-settings/AppSettings.tsx index 8b828d06b..90e4931cd 100644 --- a/apps/client/src/features/app-settings/AppSettings.tsx +++ b/apps/client/src/features/app-settings/AppSettings.tsx @@ -4,12 +4,12 @@ import { useKeyDown } from '../../common/hooks/useKeyDown'; import AboutPanel from './panel/about-panel/AboutPanel'; import AutomationPanel from './panel/automations-panel/AutomationPanel'; -import FeatureSettingsPanel from './panel/feature-settings-panel/FeatureSettingsPanel'; -import GeneralPanel from './panel/general-panel/GeneralPanel'; +import FeaturePanel from './panel/feature-panel/FeaturePanel'; +import ManagePanel from './panel/manage-panel/ManagePanel'; import NetworkLogPanel from './panel/network-panel/NetworkLogPanel'; import ProjectPanel from './panel/project-panel/ProjectPanel'; +import SettingsPanel from './panel/settings-panel/SettingsPanel'; import ShutdownPanel from './panel/shutdown-panel/ShutdownPanel'; -import SourcesPanel from './panel/sources-panel/SourcesPanel'; import PanelContent from './panel-content/PanelContent'; import PanelList from './panel-list/PanelList'; import useAppSettingsNavigation from './useAppSettingsNavigation'; @@ -25,11 +25,11 @@ export default function AppSettings() { + {panel === 'settings' && } {panel === 'project' && } - {panel === 'general' && } - {panel === 'feature_settings' && } - {panel === 'sources' && } + {panel === 'manage' && } {panel === 'automation' && } + {panel === 'sharing' && } {panel === 'network' && } {panel === 'about' && } {panel === 'shutdown' && } diff --git a/apps/client/src/features/app-settings/panel-list/PanelList.tsx b/apps/client/src/features/app-settings/panel-list/PanelList.tsx index 25c239812..7406946fa 100644 --- a/apps/client/src/features/app-settings/panel-list/PanelList.tsx +++ b/apps/client/src/features/app-settings/panel-list/PanelList.tsx @@ -68,12 +68,12 @@ function PanelListItem(props: PanelListItemProps) { > {panel.label} - {panel.secondary?.map((secondary) => { + {panel.secondary?.map((secondary, index) => { const id = secondary.id.split('__')[1]; const secondaryClasses = cx([style.secondary, isSelected && location === id ? style.active : null]); return (
  • setLocation(secondary.id as SettingsOptionId)} onKeyDown={(event) => { isKeyEnter(event) && setLocation(secondary.id as SettingsOptionId); diff --git a/apps/client/src/features/app-settings/panel-utils/PanelUtils.module.scss b/apps/client/src/features/app-settings/panel-utils/PanelUtils.module.scss index e49ba1885..2e5ef678e 100644 --- a/apps/client/src/features/app-settings/panel-utils/PanelUtils.module.scss +++ b/apps/client/src/features/app-settings/panel-utils/PanelUtils.module.scss @@ -188,6 +188,7 @@ $inner-padding: 1rem; button { margin-top: 1rem; + margin-inline: auto; } } diff --git a/apps/client/src/features/app-settings/panel-utils/PanelUtils.tsx b/apps/client/src/features/app-settings/panel-utils/PanelUtils.tsx index f69e6ca26..ceb3d0cad 100644 --- a/apps/client/src/features/app-settings/panel-utils/PanelUtils.tsx +++ b/apps/client/src/features/app-settings/panel-utils/PanelUtils.tsx @@ -1,7 +1,7 @@ import { HTMLAttributes, PropsWithChildren, ReactNode } from 'react'; import { IoAdd } from 'react-icons/io5'; -import { Button } from '@chakra-ui/react'; +import Button from '../../../common/components/buttons/Button'; import { cx } from '../../../common/utils/styleUtils'; import style from './PanelUtils.module.scss'; @@ -68,14 +68,8 @@ export function TableEmpty({ label, handleClick }: { label?: string; handleClick
    {label ?? 'No data yet'}
    {handleClick && ( - )} diff --git a/apps/client/src/features/app-settings/panel/automations-panel/AutomationForm.tsx b/apps/client/src/features/app-settings/panel/automations-panel/AutomationForm.tsx index 2cd880398..5acf121dc 100644 --- a/apps/client/src/features/app-settings/panel/automations-panel/AutomationForm.tsx +++ b/apps/client/src/features/app-settings/panel/automations-panel/AutomationForm.tsx @@ -1,7 +1,7 @@ import { useEffect, useMemo } from 'react'; import { Controller, useFieldArray, useForm } from 'react-hook-form'; import { IoAdd, IoTrash } from 'react-icons/io5'; -import { Button, IconButton, Input, Radio, RadioGroup, Select } from '@chakra-ui/react'; +import { Radio, RadioGroup, Select } from '@chakra-ui/react'; import { Automation, AutomationDTO, @@ -15,7 +15,10 @@ import { import { addAutomation, editAutomation, testOutput } from '../../../../common/api/automation'; import { maybeAxiosError } from '../../../../common/api/utils'; +import Button from '../../../../common/components/buttons/Button'; +import IconButton from '../../../../common/components/buttons/IconButton'; import Info from '../../../../common/components/info/Info'; +import Input from '../../../../common/components/input/input/Input'; import ExternalLink from '../../../../common/components/link/external-link/ExternalLink'; import Tag from '../../../../common/components/tag/Tag'; import useAutomationSettings from '../../../../common/hooks-query/useAutomationSettings'; @@ -198,10 +201,8 @@ export default function AutomationForm(props: AutomationFormProps) { Title {errors.title?.message} @@ -272,43 +273,22 @@ export default function AutomationForm(props: AutomationFormProps) {
     
    - } - variant='ontime-ghosted' - size='sm' - color='#FA5656' // $red-500 - onClick={() => removeFilter(index)} - isDisabled={false} - isLoading={false} - /> + removeFilter(index)}> + +
  • ); })}
    -
    @@ -342,10 +322,8 @@ export default function AutomationForm(props: AutomationFormProps) { {...register(`outputs.${index}.targetIP`, { required: { value: true, message: 'Required field' }, })} - variant='ontime-filled' - size='sm' + fluid placeholder='127.0.0.1' - autoComplete='off' /> {rowErrors?.targetIP?.message} @@ -358,51 +336,32 @@ export default function AutomationForm(props: AutomationFormProps) { max: { value: 65535, message: 'Port must be within range 1024 - 65535' }, min: { value: 1024, message: 'Port must be within range 1024 - 65535' }, })} - variant='ontime-filled' - size='sm' + fluid type='number' maxLength={5} placeholder='8000' - autoComplete='off' /> {rowErrors?.targetPort?.message}
      - - } - variant='ontime-ghosted' - size='sm' - onClick={() => removeOutput(index)} - color='#FA5656' // $red-500 - /> + removeOutput(index)}> + +
    @@ -429,27 +388,20 @@ export default function AutomationForm(props: AutomationFormProps) { message: 'HTTP messages should target http:// or https://', }, })} - variant='ontime-filled' - size='sm' + fluid placeholder='http://127.0.0.1/start/1' - autoComplete='off' /> {rowErrors?.url?.message}
      - - } - variant='ontime-ghosted' - size='sm' - onClick={() => removeOutput(index)} - color='#FA5656' // $red-500 - /> + removeOutput(index)}> + +
    @@ -479,17 +431,12 @@ export default function AutomationForm(props: AutomationFormProps) { >   - - } - variant='ontime-ghosted' - size='sm' - onClick={() => removeOutput(index)} - color='#FA5656' // $red-500 - /> + removeOutput(index)}> + + @@ -500,24 +447,22 @@ export default function AutomationForm(props: AutomationFormProps) { return null; })} - - - {errors?.root && {errors.root.message}} - - + diff --git a/apps/client/src/features/app-settings/panel/automations-panel/AutomationSettingsForm.tsx b/apps/client/src/features/app-settings/panel/automations-panel/AutomationSettingsForm.tsx index c71b7f761..9673b26fe 100644 --- a/apps/client/src/features/app-settings/panel/automations-panel/AutomationSettingsForm.tsx +++ b/apps/client/src/features/app-settings/panel/automations-panel/AutomationSettingsForm.tsx @@ -1,9 +1,11 @@ import { Controller, useForm } from 'react-hook-form'; -import { Button, Input, Switch } from '@chakra-ui/react'; +import { Switch } from '@chakra-ui/react'; import { editAutomationSettings } from '../../../../common/api/automation'; import { maybeAxiosError } from '../../../../common/api/utils'; +import Button from '../../../../common/components/buttons/Button'; import Info from '../../../../common/components/info/Info'; +import Input from '../../../../common/components/input/input/Input'; import ExternalLink from '../../../../common/components/link/external-link/ExternalLink'; import { preventEscape } from '../../../../common/utils/keyEvent'; import { isOnlyNumbers } from '../../../../common/utils/regex'; @@ -57,16 +59,15 @@ export default function AutomationSettingsForm(props: AutomationSettingsProps) { Automation settings - @@ -139,13 +140,10 @@ export default function AutomationSettingsForm(props: AutomationSettingsProps) { Manage automations @@ -94,21 +92,19 @@ export default function AutomationsList(props: AutomationsListProps) { {automations[automationId].outputs.length} } + variant='ghosted-white' aria-label='Edit entry' onClick={() => setAutomationFormData(automations[automationId])} - /> + > + + } + variant='ghosted-destructive' aria-label='Delete entry' onClick={() => handleDelete(automationId)} - /> + > + + {deleteError && ( diff --git a/apps/client/src/features/app-settings/panel/automations-panel/OntimeActionForm.tsx b/apps/client/src/features/app-settings/panel/automations-panel/OntimeActionForm.tsx index 21b10403f..d31d56b52 100644 --- a/apps/client/src/features/app-settings/panel/automations-panel/OntimeActionForm.tsx +++ b/apps/client/src/features/app-settings/panel/automations-panel/OntimeActionForm.tsx @@ -1,8 +1,9 @@ import { PropsWithChildren, useState } from 'react'; import { UseFormRegister, UseFormSetValue } from 'react-hook-form'; -import { Input, Select } from '@chakra-ui/react'; +import { Select } from '@chakra-ui/react'; import { AutomationDTO, OntimeAction } from 'ontime-types'; +import Input from '../../../../common/components/input/input/Input'; import { cx } from '../../../../common/utils/styleUtils'; import * as Panel from '../../panel-utils/PanelUtils'; @@ -67,10 +68,8 @@ export default function OntimeActionForm(props: PropsWithChildren {rowErrors?.time?.message} @@ -80,13 +79,7 @@ export default function OntimeActionForm(props: PropsWithChildren - - diff --git a/apps/client/src/features/app-settings/panel/automations-panel/TriggersList.tsx b/apps/client/src/features/app-settings/panel/automations-panel/TriggersList.tsx index b4703c8cd..531994cc6 100644 --- a/apps/client/src/features/app-settings/panel/automations-panel/TriggersList.tsx +++ b/apps/client/src/features/app-settings/panel/automations-panel/TriggersList.tsx @@ -1,10 +1,10 @@ import { Fragment, useMemo, useState } from 'react'; import { IoAdd } from 'react-icons/io5'; -import { Button } from '@chakra-ui/react'; import { NormalisedAutomation, Trigger } from 'ontime-types'; import { deleteTrigger } from '../../../../common/api/automation'; import { maybeAxiosError } from '../../../../common/api/utils'; +import Button from '../../../../common/components/buttons/Button'; import useAutomationSettings from '../../../../common/hooks-query/useAutomationSettings'; import * as Panel from '../../panel-utils/PanelUtils'; @@ -47,17 +47,8 @@ export default function TriggersList(props: TriggersListProps) { Manage triggers - diff --git a/apps/client/src/features/app-settings/panel/automations-panel/TriggersListItem.tsx b/apps/client/src/features/app-settings/panel/automations-panel/TriggersListItem.tsx index 491c86e83..cadd0127c 100644 --- a/apps/client/src/features/app-settings/panel/automations-panel/TriggersListItem.tsx +++ b/apps/client/src/features/app-settings/panel/automations-panel/TriggersListItem.tsx @@ -1,8 +1,8 @@ import { useState } from 'react'; import { IoPencil, IoTrash, IoWarningOutline } from 'react-icons/io5'; -import { IconButton } from '@chakra-ui/react'; import { NormalisedAutomation, TimerLifeCycle } from 'ontime-types'; +import IconButton from '../../../../common/components/buttons/IconButton'; import Tag from '../../../../common/components/tag/Tag'; import * as Panel from '../../panel-utils/PanelUtils'; @@ -62,22 +62,12 @@ export default function TriggersListItem(props: TriggersListItemProps) { {automations?.[automationId]?.title} - } - aria-label='Edit entry' - onClick={() => setIsEditing(true)} - /> - } - aria-label='Delete entry' - onClick={handleDelete} - /> + setIsEditing(true)}> + + + + + ); diff --git a/apps/client/src/features/app-settings/panel/automations-panel/template-input/TemplateInput.tsx b/apps/client/src/features/app-settings/panel/automations-panel/template-input/TemplateInput.tsx index 6c6148856..0992f3239 100644 --- a/apps/client/src/features/app-settings/panel/automations-panel/template-input/TemplateInput.tsx +++ b/apps/client/src/features/app-settings/panel/automations-panel/template-input/TemplateInput.tsx @@ -1,7 +1,7 @@ import { forwardRef, useMemo, useState } from 'react'; -import { type InputProps, Input } from '@chakra-ui/react'; import { mergeRefs, useClickOutside } from '@mantine/hooks'; +import Input, { type InputProps } from '../../../../../common/components/input/input/Input'; import useCustomFields from '../../../../../common/hooks-query/useCustomFields'; import { makeAutoCompleteList, matchRemaining, selectFromLastTemplate } from './templateInput.utils'; @@ -53,7 +53,7 @@ const TemplateInput = forwardRef(function TemplateInput(props: TemplateInputProp return (
    - + {showSuggestions && suggestions.length > 0 && (
      {suggestions.map((suggestion) => ( diff --git a/apps/client/src/features/app-settings/panel/feature-panel/FeaturePanel.module.scss b/apps/client/src/features/app-settings/panel/feature-panel/FeaturePanel.module.scss new file mode 100644 index 000000000..6d319630a --- /dev/null +++ b/apps/client/src/features/app-settings/panel/feature-panel/FeaturePanel.module.scss @@ -0,0 +1,11 @@ +.fit { + width: fit-content; +} + +.aliasConstrain { + min-width: 12em; +} + +.fullWidth { + width: 100%; +} diff --git a/apps/client/src/features/app-settings/panel/feature-panel/FeaturePanel.tsx b/apps/client/src/features/app-settings/panel/feature-panel/FeaturePanel.tsx new file mode 100644 index 000000000..41c30c2fb --- /dev/null +++ b/apps/client/src/features/app-settings/panel/feature-panel/FeaturePanel.tsx @@ -0,0 +1,42 @@ +import useScrollIntoView from '../../../../common/hooks/useScrollIntoView'; +import { isOntimeCloud } from '../../../../externals'; +import type { PanelBaseProps } from '../../panel-list/PanelList'; +import * as Panel from '../../panel-utils/PanelUtils'; +import InfoNif from '../network-panel/NetworkInterfaces'; + +import GenerateLinkFormExport from './GenerateLinkFormExport'; +import ReportSettings from './ReportSettings'; +import UrlPresetsForm from './UrlPresetsForm'; + +export default function FeaturePanel({ location }: PanelBaseProps) { + const presetsRef = useScrollIntoView('presets', location); + const linkRef = useScrollIntoView('link', location); + const reportRef = useScrollIntoView('report', location); + + return ( + <> + Sharing and reporting +
      + +
      +
      + + + Share Ontime Link + + {!isOntimeCloud && ( + <> + Ontime is streaming on the following network interfaces + + + )} + + + +
      +
      + +
      + + ); +} diff --git a/apps/client/src/features/app-settings/panel/network-panel/GenerateLinkForm.module.scss b/apps/client/src/features/app-settings/panel/feature-panel/GenerateLinkForm.module.scss similarity index 100% rename from apps/client/src/features/app-settings/panel/network-panel/GenerateLinkForm.module.scss rename to apps/client/src/features/app-settings/panel/feature-panel/GenerateLinkForm.module.scss diff --git a/apps/client/src/features/app-settings/panel/network-panel/GenerateLinkForm.tsx b/apps/client/src/features/app-settings/panel/feature-panel/GenerateLinkForm.tsx similarity index 100% rename from apps/client/src/features/app-settings/panel/network-panel/GenerateLinkForm.tsx rename to apps/client/src/features/app-settings/panel/feature-panel/GenerateLinkForm.tsx diff --git a/apps/client/src/features/app-settings/panel/network-panel/GenerateLinkFormExport.tsx b/apps/client/src/features/app-settings/panel/feature-panel/GenerateLinkFormExport.tsx similarity index 100% rename from apps/client/src/features/app-settings/panel/network-panel/GenerateLinkFormExport.tsx rename to apps/client/src/features/app-settings/panel/feature-panel/GenerateLinkFormExport.tsx diff --git a/apps/client/src/features/app-settings/panel/feature-settings-panel/ReportSettings.module.scss b/apps/client/src/features/app-settings/panel/feature-panel/ReportSettings.module.scss similarity index 100% rename from apps/client/src/features/app-settings/panel/feature-settings-panel/ReportSettings.module.scss rename to apps/client/src/features/app-settings/panel/feature-panel/ReportSettings.module.scss diff --git a/apps/client/src/features/app-settings/panel/feature-settings-panel/ReportSettings.tsx b/apps/client/src/features/app-settings/panel/feature-panel/ReportSettings.tsx similarity index 85% rename from apps/client/src/features/app-settings/panel/feature-settings-panel/ReportSettings.tsx rename to apps/client/src/features/app-settings/panel/feature-panel/ReportSettings.tsx index 0d0926b1f..f7b25eae7 100644 --- a/apps/client/src/features/app-settings/panel/feature-settings-panel/ReportSettings.tsx +++ b/apps/client/src/features/app-settings/panel/feature-panel/ReportSettings.tsx @@ -1,9 +1,9 @@ import { useMemo } from 'react'; import { IoTrashBin } from 'react-icons/io5'; -import { Button } from '@chakra-ui/react'; import { deleteAllReport } from '../../../../common/api/report'; import { createBlob, downloadBlob } from '../../../../common/api/utils'; +import Button from '../../../../common/components/buttons/Button'; import useReport from '../../../../common/hooks-query/useReport'; import useRundown from '../../../../common/hooks-query/useRundown'; import { cx } from '../../../../common/utils/styleUtils'; @@ -41,23 +41,12 @@ export default function ReportSettings() { Manage report - - diff --git a/apps/client/src/features/app-settings/panel/feature-settings-panel/UrlPresetsForm.tsx b/apps/client/src/features/app-settings/panel/feature-panel/UrlPresetsForm.tsx similarity index 89% rename from apps/client/src/features/app-settings/panel/feature-settings-panel/UrlPresetsForm.tsx rename to apps/client/src/features/app-settings/panel/feature-panel/UrlPresetsForm.tsx index db7553550..8411a9360 100644 --- a/apps/client/src/features/app-settings/panel/feature-settings-panel/UrlPresetsForm.tsx +++ b/apps/client/src/features/app-settings/panel/feature-panel/UrlPresetsForm.tsx @@ -1,13 +1,16 @@ import { useEffect } from 'react'; import { useFieldArray, useForm } from 'react-hook-form'; import { IoAdd, IoOpenOutline, IoTrash } from 'react-icons/io5'; -import { Button, IconButton, Input, Switch } from '@chakra-ui/react'; +import { Switch } from '@chakra-ui/react'; import { URLPreset } from 'ontime-types'; import { postUrlPresets } from '../../../../common/api/urlPresets'; import { maybeAxiosError } from '../../../../common/api/utils'; +import Button from '../../../../common/components/buttons/Button'; +import IconButton from '../../../../common/components/buttons/IconButton'; import TooltipActionBtn from '../../../../common/components/buttons/TooltipActionBtn'; import Info from '../../../../common/components/info/Info'; +import Input from '../../../../common/components/input/input/Input'; import ExternalLink from '../../../../common/components/link/external-link/ExternalLink'; import useUrlPresets from '../../../../common/hooks-query/useUrlPresets'; import { preventEscape } from '../../../../common/utils/keyEvent'; @@ -15,7 +18,7 @@ import { handleLinks } from '../../../../common/utils/linkUtils'; import { validateUrlPresetPath } from '../../../../common/utils/urlPresets'; import * as Panel from '../../panel-utils/PanelUtils'; -import style from './FeatureSettings.module.scss'; +import style from './FeaturePanel.module.scss'; const urlPresetsDocs = 'https://docs.getontime.no/features/url-presets/'; @@ -98,10 +101,10 @@ export default function UrlPresetsForm() { URL presets - - @@ -134,8 +137,8 @@ export default function UrlPresetsForm() { Manage presets - {errors?.root && {errors.root.message}} @@ -173,11 +176,9 @@ export default function UrlPresetsForm() { {...register(`data.${index}.alias`, { required: { value: true, message: 'Required field' }, })} - size='sm' - variant='ontime-filled' + fluid placeholder='URL Preset' data-testid={`field__alias_${index}`} - autoComplete='off' /> {maybeAliasError} @@ -186,11 +187,9 @@ export default function UrlPresetsForm() { {...register(`data.${index}.pathAndParams`, { required: { value: true, message: 'Required field' }, })} - size='sm' - variant='ontime-filled' + fluid placeholder='URL (portion after ontime Port)' data-testid={`field__url_${index}`} - autoComplete='off' /> {maybeUrlError} @@ -207,14 +206,13 @@ export default function UrlPresetsForm() { data-testid={`field__test_${index}`} /> remove(index)} - variant='ontime-ghosted' - color='#FA5656' // $red-500 - icon={} + variant='ghosted-destructive' aria-label='Delete entry' data-testid={`field__delete_${index}`} - /> + > + + ); diff --git a/apps/client/src/features/app-settings/panel/feature-settings-panel/reportSettings.utils.ts b/apps/client/src/features/app-settings/panel/feature-panel/reportSettings.utils.ts similarity index 100% rename from apps/client/src/features/app-settings/panel/feature-settings-panel/reportSettings.utils.ts rename to apps/client/src/features/app-settings/panel/feature-panel/reportSettings.utils.ts diff --git a/apps/client/src/features/app-settings/panel/feature-settings-panel/FeatureSettingsPanel.tsx b/apps/client/src/features/app-settings/panel/feature-settings-panel/FeatureSettingsPanel.tsx deleted file mode 100644 index b636af1d7..000000000 --- a/apps/client/src/features/app-settings/panel/feature-settings-panel/FeatureSettingsPanel.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import useScrollIntoView from '../../../../common/hooks/useScrollIntoView'; -import type { PanelBaseProps } from '../../panel-list/PanelList'; -import * as Panel from '../../panel-utils/PanelUtils'; - -import CustomFields from './custom-fields/CustomFields'; -import ReportSettings from './ReportSettings'; -import UrlPresetsForm from './UrlPresetsForm'; - -export default function FeatureSettingsPanel({ location }: PanelBaseProps) { - const customFieldsRef = useScrollIntoView('custom', location); - const urlPresetsRef = useScrollIntoView('urlpresets', location); - const reportRef = useScrollIntoView('report', location); - - return ( - <> - Feature Settings -
      - -
      - -
      - -
      - -
      - -
      - - ); -} diff --git a/apps/client/src/features/app-settings/panel/general-panel/GeneralPanel.tsx b/apps/client/src/features/app-settings/panel/general-panel/GeneralPanel.tsx deleted file mode 100644 index c54e667da..000000000 --- a/apps/client/src/features/app-settings/panel/general-panel/GeneralPanel.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import useScrollIntoView from '../../../../common/hooks/useScrollIntoView'; -import type { PanelBaseProps } from '../../panel-list/PanelList'; -import * as Panel from '../../panel-utils/PanelUtils'; -import EditorSettingsForm from '../interface-panel/EditorSettingsForm'; - -import GeneralPanelForm from './GeneralPanelForm'; -import ViewSettingsForm from './ViewSettingsForm'; - -export default function GeneralPanel({ location }: PanelBaseProps) { - const generalRef = useScrollIntoView('settings', location); - const editorRef = useScrollIntoView('editor', location); - const viewRef = useScrollIntoView('view', location); - - return ( - <> - App Settings -
      - -
      -
      - -
      -
      - -
      - - ); -} diff --git a/apps/client/src/features/app-settings/panel/feature-settings-panel/custom-fields/CustomFields.tsx b/apps/client/src/features/app-settings/panel/manage-panel/CustomFields.tsx similarity index 70% rename from apps/client/src/features/app-settings/panel/feature-settings-panel/custom-fields/CustomFields.tsx rename to apps/client/src/features/app-settings/panel/manage-panel/CustomFields.tsx index 243a2d6f0..764d7fa1a 100644 --- a/apps/client/src/features/app-settings/panel/feature-settings-panel/custom-fields/CustomFields.tsx +++ b/apps/client/src/features/app-settings/panel/manage-panel/CustomFields.tsx @@ -1,19 +1,19 @@ import { useState } from 'react'; import { IoAdd } from 'react-icons/io5'; -import { Button } from '@chakra-ui/react'; import { CustomField, CustomFieldKey } from 'ontime-types'; -import { deleteCustomField, editCustomField, postCustomField } from '../../../../../common/api/customFields'; -import Info from '../../../../../common/components/info/Info'; -import ExternalLink from '../../../../../common/components/link/external-link/ExternalLink'; -import useCustomFields from '../../../../../common/hooks-query/useCustomFields'; -import { customFieldsDocsUrl } from '../../../../../externals'; -import * as Panel from '../../../panel-utils/PanelUtils'; +import { deleteCustomField, editCustomField, postCustomField } from '../../../../common/api/customFields'; +import Button from '../../../../common/components/buttons/Button'; +import Info from '../../../../common/components/info/Info'; +import ExternalLink from '../../../../common/components/link/external-link/ExternalLink'; +import useCustomFields from '../../../../common/hooks-query/useCustomFields'; +import { customFieldsDocsUrl } from '../../../../externals'; +import * as Panel from '../../panel-utils/PanelUtils'; -import CustomFieldEntry from './CustomFieldEntry'; -import CustomFieldForm from './CustomFieldForm'; +import CustomFieldEntry from './composite/CustomFieldEntry'; +import CustomFieldForm from './composite/CustomFieldForm'; -export default function CustomFields() { +export default function CustomFieldSettings() { const { data, refetch } = useCustomFields(); const [isAdding, setIsAdding] = useState(false); @@ -50,8 +50,8 @@ export default function CustomFields() { Custom fields - @@ -60,11 +60,7 @@ export default function CustomFields() { Custom fields allow for additional information to be added to an event.

      - This data is not used by Ontime, but provides place for cueing or department specific information (eg. - light, sound, camera). -
      -
      - Custom fields can be used width the Integrations feature using the generated key. + This data can be used in the Automation feature by using the generated key. See the docs diff --git a/apps/client/src/features/app-settings/panel/feature-settings-panel/FeatureSettings.module.scss b/apps/client/src/features/app-settings/panel/manage-panel/ManagePanel.module.scss similarity index 79% rename from apps/client/src/features/app-settings/panel/feature-settings-panel/FeatureSettings.module.scss rename to apps/client/src/features/app-settings/panel/manage-panel/ManagePanel.module.scss index 651b27a58..2488127e6 100644 --- a/apps/client/src/features/app-settings/panel/feature-settings-panel/FeatureSettings.module.scss +++ b/apps/client/src/features/app-settings/panel/manage-panel/ManagePanel.module.scss @@ -14,16 +14,12 @@ gap: 1rem; } -.fit { - width: fit-content; -} - -.aliasConstrain { - min-width: 12em; -} - .twoCols { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; } + +.current { + background-color: $blue-1100; +} diff --git a/apps/client/src/features/app-settings/panel/manage-panel/ManagePanel.tsx b/apps/client/src/features/app-settings/panel/manage-panel/ManagePanel.tsx new file mode 100644 index 000000000..aca6a5ccc --- /dev/null +++ b/apps/client/src/features/app-settings/panel/manage-panel/ManagePanel.tsx @@ -0,0 +1,33 @@ +import useScrollIntoView from '../../../../common/hooks/useScrollIntoView'; +import type { PanelBaseProps } from '../../panel-list/PanelList'; +import * as Panel from '../../panel-utils/PanelUtils'; + +import SourcesPanel from './sources-panel/SourcesPanel'; +import CustomFieldSettings from './CustomFields'; +import ManageRundowns from './ManageRundowns'; +import RundownDefaultSettings from './RundownDefaultSettings'; + +export default function ManagePanel({ location }: PanelBaseProps) { + const defaultsRef = useScrollIntoView('defaults', location); + const customRef = useScrollIntoView('custom', location); + const rundownsRef = useScrollIntoView('rundowns', location); + const sheetsRef = useScrollIntoView('sheets', location); + + return ( + <> + Project data +
      + +
      +
      + +
      +
      + +
      +
      + +
      + + ); +} diff --git a/apps/client/src/features/app-settings/panel/project-panel/ManageRundowns.tsx b/apps/client/src/features/app-settings/panel/manage-panel/ManageRundowns.tsx similarity index 98% rename from apps/client/src/features/app-settings/panel/project-panel/ManageRundowns.tsx rename to apps/client/src/features/app-settings/panel/manage-panel/ManageRundowns.tsx index d27d7a820..513d04ae1 100644 --- a/apps/client/src/features/app-settings/panel/project-panel/ManageRundowns.tsx +++ b/apps/client/src/features/app-settings/panel/manage-panel/ManageRundowns.tsx @@ -7,7 +7,7 @@ import { useProjectRundowns } from '../../../../common/hooks-query/useProjectRun import { cx } from '../../../../common/utils/styleUtils'; import * as Panel from '../../panel-utils/PanelUtils'; -import style from './ProjectPanel.module.scss'; +import style from './ManagePanel.module.scss'; export default function ManageRundowns() { const { data } = useProjectRundowns(); diff --git a/apps/client/src/features/app-settings/panel/interface-panel/EditorSettingsForm.tsx b/apps/client/src/features/app-settings/panel/manage-panel/RundownDefaultSettings.tsx similarity index 74% rename from apps/client/src/features/app-settings/panel/interface-panel/EditorSettingsForm.tsx rename to apps/client/src/features/app-settings/panel/manage-panel/RundownDefaultSettings.tsx index a080e0956..037c9078c 100644 --- a/apps/client/src/features/app-settings/panel/interface-panel/EditorSettingsForm.tsx +++ b/apps/client/src/features/app-settings/panel/manage-panel/RundownDefaultSettings.tsx @@ -6,7 +6,7 @@ import TimeInput from '../../../../common/components/input/time-input/TimeInput' import { editorSettingsDefaults, useEditorSettings } from '../../../../common/stores/editorSettings'; import * as Panel from '../../panel-utils/PanelUtils'; -export default function EditorSettingsForm() { +export default function RundownDefaultSettings() { const { defaultDuration, linkPrevious, @@ -31,10 +31,10 @@ export default function EditorSettingsForm() { return ( - Editor settings + Rundown defaults - Rundown defaults for new events + Default settings for new events - - Run mode - - - - - - - - - - - - - Edit mode - - - - - - - - - - - ); diff --git a/apps/client/src/features/app-settings/panel/feature-settings-panel/custom-fields/CustomFieldEntry.tsx b/apps/client/src/features/app-settings/panel/manage-panel/composite/CustomFieldEntry.tsx similarity index 76% rename from apps/client/src/features/app-settings/panel/feature-settings-panel/custom-fields/CustomFieldEntry.tsx rename to apps/client/src/features/app-settings/panel/manage-panel/composite/CustomFieldEntry.tsx index 351beadec..629df80d8 100644 --- a/apps/client/src/features/app-settings/panel/feature-settings-panel/custom-fields/CustomFieldEntry.tsx +++ b/apps/client/src/features/app-settings/panel/manage-panel/composite/CustomFieldEntry.tsx @@ -1,8 +1,8 @@ import { useState } from 'react'; import { IoPencil, IoTrash } from 'react-icons/io5'; -import { IconButton } from '@chakra-ui/react'; import { CustomField, CustomFieldKey } from 'ontime-types'; +import IconButton from '../../../../../common/components/buttons/IconButton'; import CopyTag from '../../../../../common/components/copy-tag/CopyTag'; import Swatch from '../../../../../common/components/input/colour-input/Swatch'; import Tag from '../../../../../common/components/tag/Tag'; @@ -10,7 +10,7 @@ import * as Panel from '../../../panel-utils/PanelUtils'; import CustomFieldForm from './CustomFieldForm'; -import style from '../FeatureSettings.module.scss'; +import style from '../ManagePanel.module.scss'; interface CustomFieldEntryProps { colour: string; @@ -61,22 +61,12 @@ export default function CustomFieldEntry(props: CustomFieldEntryProps) { - } - aria-label='Edit entry' - onClick={() => setIsEditing(true)} - /> - } - aria-label='Delete entry' - onClick={() => onDelete(fieldKey)} - /> + setIsEditing(true)}> + + + onDelete(fieldKey)}> + + ); diff --git a/apps/client/src/features/app-settings/panel/feature-settings-panel/custom-fields/CustomFieldForm.tsx b/apps/client/src/features/app-settings/panel/manage-panel/composite/CustomFieldForm.tsx similarity index 90% rename from apps/client/src/features/app-settings/panel/feature-settings-panel/custom-fields/CustomFieldForm.tsx rename to apps/client/src/features/app-settings/panel/manage-panel/composite/CustomFieldForm.tsx index 5e3cc9a77..595b7b945 100644 --- a/apps/client/src/features/app-settings/panel/feature-settings-panel/custom-fields/CustomFieldForm.tsx +++ b/apps/client/src/features/app-settings/panel/manage-panel/composite/CustomFieldForm.tsx @@ -1,17 +1,19 @@ import { useEffect, useState } from 'react'; import { Controller, useForm } from 'react-hook-form'; -import { Button, Input, Radio, RadioGroup } from '@chakra-ui/react'; +import { Radio, RadioGroup } from '@chakra-ui/react'; import { CustomField } from 'ontime-types'; import { customFieldLabelToKey, isAlphanumericWithSpace } from 'ontime-utils'; import { maybeAxiosError } from '../../../../../common/api/utils'; +import Button from '../../../../../common/components/buttons/Button'; import Info from '../../../../../common/components/info/Info'; import SwatchSelect from '../../../../../common/components/input/colour-input/SwatchSelect'; +import Input from '../../../../../common/components/input/input/Input'; import useCustomFields from '../../../../../common/hooks-query/useCustomFields'; import { preventEscape } from '../../../../../common/utils/keyEvent'; import * as Panel from '../../../panel-utils/PanelUtils'; -import style from '../FeatureSettings.module.scss'; +import style from '../ManagePanel.module.scss'; interface CustomFieldsFormProps { onSubmit: (field: CustomField) => Promise; @@ -118,15 +120,13 @@ export default function CustomFieldForm(props: CustomFieldsFormProps) { return true; }, })} - size='sm' - variant='ontime-filled' - autoComplete='off' + fluid />
    Key (use in Integrations and API) - +
    @@ -135,10 +135,10 @@ export default function CustomFieldForm(props: CustomFieldsFormProps) {
    {errors.root && {errors.root.message}} - - diff --git a/apps/client/src/features/app-settings/panel/sources-panel/GSheetInfo.tsx b/apps/client/src/features/app-settings/panel/manage-panel/sources-panel/GSheetInfo.tsx similarity index 78% rename from apps/client/src/features/app-settings/panel/sources-panel/GSheetInfo.tsx rename to apps/client/src/features/app-settings/panel/manage-panel/sources-panel/GSheetInfo.tsx index adf8d0cf5..612cee61d 100644 --- a/apps/client/src/features/app-settings/panel/sources-panel/GSheetInfo.tsx +++ b/apps/client/src/features/app-settings/panel/manage-panel/sources-panel/GSheetInfo.tsx @@ -1,5 +1,5 @@ -import Info from '../../../../common/components/info/Info'; -import ExternalLink from '../../../../common/components/link/external-link/ExternalLink'; +import Info from '../../../../../common/components/info/Info'; +import ExternalLink from '../../../../../common/components/link/external-link/ExternalLink'; const googleSheetDocsUrl = 'https://docs.getontime.no/features/import-spreadsheet-gsheet/'; diff --git a/apps/client/src/features/app-settings/panel/sources-panel/GSheetSetup.tsx b/apps/client/src/features/app-settings/panel/manage-panel/sources-panel/GSheetSetup.tsx similarity index 77% rename from apps/client/src/features/app-settings/panel/sources-panel/GSheetSetup.tsx rename to apps/client/src/features/app-settings/panel/manage-panel/sources-panel/GSheetSetup.tsx index 5762bdd5d..d77a19e06 100644 --- a/apps/client/src/features/app-settings/panel/sources-panel/GSheetSetup.tsx +++ b/apps/client/src/features/app-settings/panel/manage-panel/sources-panel/GSheetSetup.tsx @@ -1,12 +1,13 @@ import { ChangeEvent, useEffect, useState } from 'react'; import { IoCheckmark, IoShieldCheckmarkOutline } from 'react-icons/io5'; -import { Button, Input, Spinner } from '@chakra-ui/react'; -import { getWorksheetNames } from '../../../../common/api/sheets'; -import { maybeAxiosError } from '../../../../common/api/utils'; -import CopyTag from '../../../../common/components/copy-tag/CopyTag'; -import { openLink } from '../../../../common/utils/linkUtils'; -import * as Panel from '../../panel-utils/PanelUtils'; +import { getWorksheetNames } from '../../../../../common/api/sheets'; +import { maybeAxiosError } from '../../../../../common/api/utils'; +import Button from '../../../../../common/components/buttons/Button'; +import CopyTag from '../../../../../common/components/copy-tag/CopyTag'; +import Input from '../../../../../common/components/input/input/Input'; +import { openLink } from '../../../../../common/utils/linkUtils'; +import * as Panel from '../../../panel-utils/PanelUtils'; import useGoogleSheet from './useGoogleSheet'; import { useSheetStore } from './useSheetStore'; @@ -138,50 +139,33 @@ export default function GSheetSetup(props: GSheetSetupProps) { Sync with Google Sheet (experimental) {isAuthenticated ? ( - ) : ( - + )} Upload Client Secret provided by Google {authenticationError} - + Enter ID of sheet to synchronise {undefined} setSheetId(event.target.value)} - isDisabled={isLoading || canAuthenticate} + disabled={isLoading || canAuthenticate} /> {!canAuthenticate ? ( - @@ -189,17 +173,12 @@ export default function GSheetSetup(props: GSheetSetupProps) { ) : ( - {isAuthenticating && } + {isAuthenticating && Authenticating...} {authKey ? authKey : 'Upload files to generate Auth Key'} - diff --git a/apps/client/src/features/app-settings/panel/sources-panel/ImportReview.tsx b/apps/client/src/features/app-settings/panel/manage-panel/sources-panel/ImportReview.tsx similarity index 81% rename from apps/client/src/features/app-settings/panel/sources-panel/ImportReview.tsx rename to apps/client/src/features/app-settings/panel/manage-panel/sources-panel/ImportReview.tsx index d5ac93e42..ce78814e7 100644 --- a/apps/client/src/features/app-settings/panel/sources-panel/ImportReview.tsx +++ b/apps/client/src/features/app-settings/panel/manage-panel/sources-panel/ImportReview.tsx @@ -1,8 +1,8 @@ import { useState } from 'react'; -import { Button } from '@chakra-ui/react'; import { CustomFields, Rundown } from 'ontime-types'; -import * as Panel from '../../panel-utils/PanelUtils'; +import Button from '../../../../../common/components/buttons/Button'; +import * as Panel from '../../../panel-utils/PanelUtils'; import PreviewSpreadsheet from './preview/PreviewRundown'; import useGoogleSheet from './useGoogleSheet'; @@ -44,10 +44,10 @@ export default function ImportReview(props: ImportReviewProps) { Review Rundown - - diff --git a/apps/client/src/features/app-settings/panel/sources-panel/SourcesPanel.module.scss b/apps/client/src/features/app-settings/panel/manage-panel/sources-panel/SourcesPanel.module.scss similarity index 100% rename from apps/client/src/features/app-settings/panel/sources-panel/SourcesPanel.module.scss rename to apps/client/src/features/app-settings/panel/manage-panel/sources-panel/SourcesPanel.module.scss diff --git a/apps/client/src/features/app-settings/panel/sources-panel/SourcesPanel.tsx b/apps/client/src/features/app-settings/panel/manage-panel/sources-panel/SourcesPanel.tsx similarity index 61% rename from apps/client/src/features/app-settings/panel/sources-panel/SourcesPanel.tsx rename to apps/client/src/features/app-settings/panel/manage-panel/sources-panel/SourcesPanel.tsx index 850c80669..b04f3a8c4 100644 --- a/apps/client/src/features/app-settings/panel/sources-panel/SourcesPanel.tsx +++ b/apps/client/src/features/app-settings/panel/manage-panel/sources-panel/SourcesPanel.tsx @@ -1,17 +1,18 @@ import { ChangeEvent, useRef, useState } from 'react'; import { IoCloudOutline, IoDownloadOutline } from 'react-icons/io5'; -import { Button, Input } from '@chakra-ui/react'; import { getErrorMessage, ImportMap } from 'ontime-utils'; import { getWorksheetNames as getWorksheetNamesExcel, importRundownPreview as importRundownPreviewExcel, upload as uploadExcel, -} from '../../../../common/api/excel'; -import { getWorksheetNames } from '../../../../common/api/sheets'; -import { maybeAxiosError } from '../../../../common/api/utils'; -import { validateExcelImport } from '../../../../common/utils/uploadUtils'; -import * as Panel from '../../panel-utils/PanelUtils'; +} from '../../../../../common/api/excel'; +import { getWorksheetNames } from '../../../../../common/api/sheets'; +import { maybeAxiosError } from '../../../../../common/api/utils'; +import Button from '../../../../../common/components/buttons/Button'; +import * as Editor from '../../../../../common/components/editor-utils/EditorUtils'; +import { validateExcelImport } from '../../../../../common/utils/uploadUtils'; +import * as Panel from '../../../panel-utils/PanelUtils'; import ImportMapForm from './import-map/ImportMapForm'; import GSheetInfo from './GSheetInfo'; @@ -154,87 +155,75 @@ export default function SourcesPanel() { const showReview = rundown !== null && customFields !== null; return ( - <> - Data sources - - - Synchronise your rundown with an external source - {error && {error}} - {showInput && ( - <> - - -
    -
    - - Accepts .xlsx files -
    -
    - - Start authentication process -
    + + + Synchronise your rundown with an external source + {error && {error}} + {showInput && ( + <> + + +
    +
    + + Accepts .xlsx files +
    + +
    + + Start authentication process
    - - )} - {showCompleted && ( -
    - {error ? ( - - Import failed - - ) : ( - - Import successful - - )} -
    - )} - {showAuth && } - {showImportMap && !showReview && ( - - )} - {showReview && ( - - )} - - - + + )} + {showCompleted && ( +
    + {error ? ( + + Import failed + + ) : ( + + Import successful + + )} + +
    + )} + {showAuth && } + {showImportMap && !showReview && ( + + )} + {showReview && ( + + )} + + ); } diff --git a/apps/client/src/features/app-settings/panel/sources-panel/import-map/ImportMapForm.tsx b/apps/client/src/features/app-settings/panel/manage-panel/sources-panel/import-map/ImportMapForm.tsx similarity index 84% rename from apps/client/src/features/app-settings/panel/sources-panel/import-map/ImportMapForm.tsx rename to apps/client/src/features/app-settings/panel/manage-panel/sources-panel/import-map/ImportMapForm.tsx index a678debdf..8a642bba7 100644 --- a/apps/client/src/features/app-settings/panel/sources-panel/import-map/ImportMapForm.tsx +++ b/apps/client/src/features/app-settings/panel/manage-panel/sources-panel/import-map/ImportMapForm.tsx @@ -1,10 +1,13 @@ import { useEffect, useState } from 'react'; import { useFieldArray, useForm } from 'react-hook-form'; import { IoAdd, IoTrash } from 'react-icons/io5'; -import { Button, IconButton, Input, Select, Tooltip } from '@chakra-ui/react'; +import { Select, Tooltip } from '@chakra-ui/react'; import { ImportMap, isAlphanumericWithSpace } from 'ontime-utils'; -import * as Panel from '../../../panel-utils/PanelUtils'; +import Button from '../../../../../../common/components/buttons/Button'; +import IconButton from '../../../../../../common/components/buttons/IconButton'; +import Input from '../../../../../../common/components/input/input/Input'; +import * as Panel from '../../../../panel-utils/PanelUtils'; import useGoogleSheet from '../useGoogleSheet'; import { useSheetStore } from '../useSheetStore'; @@ -95,31 +98,29 @@ export default function ImportMapForm(props: ImportMapFormProps) { {!isSpreadsheet && ( - )} - {!isSpreadsheet && ( )} @@ -168,9 +169,7 @@ export default function ImportMapForm(props: ImportMapFormProps) { } + variant='ghosted-destructive' aria-label='Delete entry' onClick={() => deleteCustomImport(index)} - /> + > + + ); @@ -233,8 +227,8 @@ export default function ImportMapForm(props: ImportMapFormProps) { - diff --git a/apps/client/src/features/app-settings/panel/sources-panel/import-map/__test__/importMapUtils.test.ts b/apps/client/src/features/app-settings/panel/manage-panel/sources-panel/import-map/__test__/importMapUtils.test.ts similarity index 100% rename from apps/client/src/features/app-settings/panel/sources-panel/import-map/__test__/importMapUtils.test.ts rename to apps/client/src/features/app-settings/panel/manage-panel/sources-panel/import-map/__test__/importMapUtils.test.ts diff --git a/apps/client/src/features/app-settings/panel/sources-panel/import-map/importMapUtils.ts b/apps/client/src/features/app-settings/panel/manage-panel/sources-panel/import-map/importMapUtils.ts similarity index 100% rename from apps/client/src/features/app-settings/panel/sources-panel/import-map/importMapUtils.ts rename to apps/client/src/features/app-settings/panel/manage-panel/sources-panel/import-map/importMapUtils.ts diff --git a/apps/client/src/features/app-settings/panel/sources-panel/preview/PreviewRundown.module.scss b/apps/client/src/features/app-settings/panel/manage-panel/sources-panel/preview/PreviewRundown.module.scss similarity index 100% rename from apps/client/src/features/app-settings/panel/sources-panel/preview/PreviewRundown.module.scss rename to apps/client/src/features/app-settings/panel/manage-panel/sources-panel/preview/PreviewRundown.module.scss diff --git a/apps/client/src/features/app-settings/panel/sources-panel/preview/PreviewRundown.tsx b/apps/client/src/features/app-settings/panel/manage-panel/sources-panel/preview/PreviewRundown.tsx similarity index 95% rename from apps/client/src/features/app-settings/panel/sources-panel/preview/PreviewRundown.tsx rename to apps/client/src/features/app-settings/panel/manage-panel/sources-panel/preview/PreviewRundown.tsx index 940d1a312..c8456aafc 100644 --- a/apps/client/src/features/app-settings/panel/sources-panel/preview/PreviewRundown.tsx +++ b/apps/client/src/features/app-settings/panel/manage-panel/sources-panel/preview/PreviewRundown.tsx @@ -3,9 +3,9 @@ import { IoLink } from 'react-icons/io5'; import { CustomFields, isOntimeBlock, isOntimeEvent, Rundown } from 'ontime-types'; import { millisToString } from 'ontime-utils'; -import Tag from '../../../../../common/components/tag/Tag'; -import { getAccessibleColour } from '../../../../../common/utils/styleUtils'; -import * as Panel from '../../../panel-utils/PanelUtils'; +import Tag from '../../../../../../common/components/tag/Tag'; +import { getAccessibleColour } from '../../../../../../common/utils/styleUtils'; +import * as Panel from '../../../../panel-utils/PanelUtils'; import style from './PreviewRundown.module.scss'; diff --git a/apps/client/src/features/app-settings/panel/sources-panel/useGoogleSheet.ts b/apps/client/src/features/app-settings/panel/manage-panel/sources-panel/useGoogleSheet.ts similarity index 92% rename from apps/client/src/features/app-settings/panel/sources-panel/useGoogleSheet.ts rename to apps/client/src/features/app-settings/panel/manage-panel/sources-panel/useGoogleSheet.ts index 3cc93c362..05a39f679 100644 --- a/apps/client/src/features/app-settings/panel/sources-panel/useGoogleSheet.ts +++ b/apps/client/src/features/app-settings/panel/manage-panel/sources-panel/useGoogleSheet.ts @@ -2,16 +2,16 @@ import { useQueryClient } from '@tanstack/react-query'; import { AuthenticationStatus, CustomFields, ProjectRundowns } from 'ontime-types'; import { ImportMap } from 'ontime-utils'; -import { CUSTOM_FIELDS, RUNDOWN } from '../../../../common/api/constants'; -import { patchData } from '../../../../common/api/db'; +import { CUSTOM_FIELDS, RUNDOWN } from '../../../../../common/api/constants'; +import { patchData } from '../../../../../common/api/db'; import { previewRundown, requestConnection, revokeAuthentication, uploadRundown, verifyAuthenticationStatus, -} from '../../../../common/api/sheets'; -import { maybeAxiosError } from '../../../../common/api/utils'; +} from '../../../../../common/api/sheets'; +import { maybeAxiosError } from '../../../../../common/api/utils'; import { useSheetStore } from './useSheetStore'; diff --git a/apps/client/src/features/app-settings/panel/sources-panel/useSheetStore.ts b/apps/client/src/features/app-settings/panel/manage-panel/sources-panel/useSheetStore.ts similarity index 100% rename from apps/client/src/features/app-settings/panel/sources-panel/useSheetStore.ts rename to apps/client/src/features/app-settings/panel/manage-panel/sources-panel/useSheetStore.ts diff --git a/apps/client/src/features/app-settings/panel/network-panel/NetworkLogPanel.tsx b/apps/client/src/features/app-settings/panel/network-panel/NetworkLogPanel.tsx index d4109ece5..dd39a260b 100644 --- a/apps/client/src/features/app-settings/panel/network-panel/NetworkLogPanel.tsx +++ b/apps/client/src/features/app-settings/panel/network-panel/NetworkLogPanel.tsx @@ -4,17 +4,14 @@ import { MessageTag } from 'ontime-types'; import useScrollIntoView from '../../../../common/hooks/useScrollIntoView'; import { usePing } from '../../../../common/hooks/useSocket'; import { sendSocket } from '../../../../common/utils/socket'; -import { isDockerImage, isOntimeCloud } from '../../../../externals'; +import { isDockerImage } from '../../../../externals'; import type { PanelBaseProps } from '../../panel-list/PanelList'; import * as Panel from '../../panel-utils/PanelUtils'; -import ClientControlPanel from '../client-control-panel/ClientControlPanel'; -import GenerateLinkFormExport from './GenerateLinkFormExport'; -import InfoNif from './NetworkInterfaces'; +import ClientControlPanel from './client-control/ClientControlPanel'; import LogExport from './NetworkLogExport'; export default function NetworkLogPanel({ location }: PanelBaseProps) { - const linkRef = useScrollIntoView('link', location); const clientsRef = useScrollIntoView('clients', location); const logRef = useScrollIntoView('log', location); @@ -26,21 +23,6 @@ export default function NetworkLogPanel({ location }: PanelBaseProps) { )} -
    - - - Share Ontime Link - - {!isOntimeCloud && ( - <> - Ontime is streaming on the following network interfaces - - - )} - - - -
    diff --git a/apps/client/src/features/app-settings/panel/client-control-panel/ClientControlPanel.module.scss b/apps/client/src/features/app-settings/panel/network-panel/client-control/ClientControlPanel.module.scss similarity index 100% rename from apps/client/src/features/app-settings/panel/client-control-panel/ClientControlPanel.module.scss rename to apps/client/src/features/app-settings/panel/network-panel/client-control/ClientControlPanel.module.scss diff --git a/apps/client/src/features/app-settings/panel/client-control-panel/ClientControlPanel.tsx b/apps/client/src/features/app-settings/panel/network-panel/client-control/ClientControlPanel.tsx similarity index 83% rename from apps/client/src/features/app-settings/panel/client-control-panel/ClientControlPanel.tsx rename to apps/client/src/features/app-settings/panel/network-panel/client-control/ClientControlPanel.tsx index c272a2001..01d5aa15f 100644 --- a/apps/client/src/features/app-settings/panel/client-control-panel/ClientControlPanel.tsx +++ b/apps/client/src/features/app-settings/panel/network-panel/client-control/ClientControlPanel.tsx @@ -1,4 +1,4 @@ -import * as Panel from '../../panel-utils/PanelUtils'; +import * as Panel from '../../../panel-utils/PanelUtils'; import ClientList from './ClientList'; diff --git a/apps/client/src/features/app-settings/panel/client-control-panel/ClientList.tsx b/apps/client/src/features/app-settings/panel/network-panel/client-control/ClientList.tsx similarity index 72% rename from apps/client/src/features/app-settings/panel/client-control-panel/ClientList.tsx rename to apps/client/src/features/app-settings/panel/network-panel/client-control/ClientList.tsx index 18c76d535..53b269e8c 100644 --- a/apps/client/src/features/app-settings/panel/client-control-panel/ClientList.tsx +++ b/apps/client/src/features/app-settings/panel/network-panel/client-control/ClientList.tsx @@ -1,32 +1,34 @@ import { useState } from 'react'; -import { Badge, Button, useDisclosure } from '@chakra-ui/react'; +import { useDisclosure } from '@mantine/hooks'; import { Client } from 'ontime-types'; -import { RedirectClientModal } from '../../../../common/components/client-modal/RedirectClientModal'; -import { RenameClientModal } from '../../../../common/components/client-modal/RenameClientModal'; -import { setClientRemote } from '../../../../common/hooks/useSocket'; -import { useClientStore } from '../../../../common/stores/clientStore'; -import * as Panel from '../../panel-utils/PanelUtils'; +import Button from '../../../../../common/components/buttons/Button'; +import { RedirectClientModal } from '../../../../../common/components/client-modal/RedirectClientModal'; +import { RenameClientModal } from '../../../../../common/components/client-modal/RenameClientModal'; +import Tag from '../../../../../common/components/tag/Tag'; +import { setClientRemote } from '../../../../../common/hooks/useSocket'; +import { useClientStore } from '../../../../../common/stores/clientStore'; +import * as Panel from '../../../panel-utils/PanelUtils'; import style from './ClientControlPanel.module.scss'; export default function ClientList() { const id = useClientStore((store) => store.id); const clients = useClientStore((store) => store.clients); - const { isOpen: isOpenRedirect, onOpen: onOpenRedirect, onClose: onCloseRedirect } = useDisclosure(); - const { isOpen: isOpenRename, onOpen: onOpenRename, onClose: onCloseRename } = useDisclosure(); + const [isOpenRedirect, redirectHandler] = useDisclosure(); + const [isOpenRename, renameHandler] = useDisclosure(); const { setIdentify } = setClientRemote; const [targetId, setTargetId] = useState(''); const openRename = (targetId: string) => { setTargetId(targetId); - onOpenRename(); + renameHandler.open(); }; const openRedirect = (targetId: string) => { setTargetId(targetId); - onOpenRedirect(); + redirectHandler.open(); }; const ontimeClients = Object.entries(clients).filter(([_, { type }]) => type === 'ontime'); @@ -43,11 +45,16 @@ export default function ClientList() { origin={targetClient.origin} currentPath={targetClient.path} isOpen={isOpenRedirect} - onClose={onCloseRedirect} + onClose={redirectHandler.close} /> )} {isOpenRename && ( - + )} Ontime Clients ({ontimeClients.length}) @@ -66,20 +73,16 @@ export default function ClientList() { return ( - {isCurrent && ( - - self - - )} + {isCurrent && SELF} {name} {path} - diff --git a/apps/client/src/features/app-settings/panel/project-panel/ProjectPanel.module.scss b/apps/client/src/features/app-settings/panel/project-panel/ProjectPanel.module.scss index 663b7f9f6..9d95819e3 100644 --- a/apps/client/src/features/app-settings/panel/project-panel/ProjectPanel.module.scss +++ b/apps/client/src/features/app-settings/panel/project-panel/ProjectPanel.module.scss @@ -45,36 +45,11 @@ } } -.uploadLogoCard { - display: flex; - gap: 1rem; - justify-content: center; - align-items: center; - flex-direction: column; - - background-color: $gray-1350; - border: 1px solid $white-10; - border-radius: 3px; - - img { - max-width: 250px; - height: auto; - } +.warningInfo { + margin-bottom: 1rem; } -.customDataItem { - width: 100%; - display: flex; - flex-direction: column; - gap: 0.5rem; - - .titleRow{ - display: flex; - gap: 1rem; - align-items: end; - - label { - flex: 1; - } - } -} +.empty { + height: 300px; + position: relative; +} \ No newline at end of file diff --git a/apps/client/src/features/app-settings/panel/project-panel/ProjectPanel.tsx b/apps/client/src/features/app-settings/panel/project-panel/ProjectPanel.tsx index 502d10d0b..9a2a35352 100644 --- a/apps/client/src/features/app-settings/panel/project-panel/ProjectPanel.tsx +++ b/apps/client/src/features/app-settings/panel/project-panel/ProjectPanel.tsx @@ -5,16 +5,12 @@ import QuickStart from '../../quick-start/QuickStart'; import type { SettingsOptionId } from '../../useAppSettingsMenu'; import ManageProjects from './ManageProjects'; -import ManageRundowns from './ManageRundowns'; -import ProjectData from './ProjectData'; interface ProjectPanelProps extends PanelBaseProps { setLocation: (location: SettingsOptionId) => void; } export default function ProjectPanel({ location, setLocation }: ProjectPanelProps) { - const projectRef = useScrollIntoView('data', location); - const manageRundownsRef = useScrollIntoView('rundowns', location); const manageProjectsRef = useScrollIntoView('list', location); const handleQuickClose = () => { @@ -25,12 +21,6 @@ export default function ProjectPanel({ location, setLocation }: ProjectPanelProp <> Project -
    - -
    -
    - -
    diff --git a/apps/client/src/features/app-settings/panel/general-panel/GeneralPanelForm.tsx b/apps/client/src/features/app-settings/panel/settings-panel/GeneralSettings.tsx similarity index 89% rename from apps/client/src/features/app-settings/panel/general-panel/GeneralPanelForm.tsx rename to apps/client/src/features/app-settings/panel/settings-panel/GeneralSettings.tsx index e041094c1..2f2342cd1 100644 --- a/apps/client/src/features/app-settings/panel/general-panel/GeneralPanelForm.tsx +++ b/apps/client/src/features/app-settings/panel/settings-panel/GeneralSettings.tsx @@ -1,19 +1,21 @@ import { useEffect } from 'react'; import { useForm } from 'react-hook-form'; -import { Button, Input, Select } from '@chakra-ui/react'; +import { Select } from '@chakra-ui/react'; import { Settings } from 'ontime-types'; import { postSettings } from '../../../../common/api/settings'; import { maybeAxiosError } from '../../../../common/api/utils'; +import Button from '../../../../common/components/buttons/Button'; +import Input from '../../../../common/components/input/input/Input'; import useSettings from '../../../../common/hooks-query/useSettings'; import { preventEscape } from '../../../../common/utils/keyEvent'; import { isOnlyNumbers } from '../../../../common/utils/regex'; import { isOntimeCloud } from '../../../../externals'; import * as Panel from '../../panel-utils/PanelUtils'; -import GeneralPinInput from './GeneralPinInput'; +import GeneralPinInput from './composite/GeneralPinInput'; -export default function GeneralPanelForm() { +export default function GeneralSettings() { const { data, status, refetch } = useSettings(); const { handleSubmit, @@ -69,17 +71,10 @@ export default function GeneralPanelForm() { General settings - - @@ -101,12 +96,10 @@ export default function GeneralPanelForm() { /> ('data', location); + const generalRef = useScrollIntoView('general', location); + const viewRef = useScrollIntoView('view', location); + + return ( + <> + Settings +
    + +
    +
    + +
    +
    + +
    + + ); +} diff --git a/apps/client/src/features/app-settings/panel/general-panel/ViewSettingsForm.tsx b/apps/client/src/features/app-settings/panel/settings-panel/ViewSettings.tsx similarity index 73% rename from apps/client/src/features/app-settings/panel/general-panel/ViewSettingsForm.tsx rename to apps/client/src/features/app-settings/panel/settings-panel/ViewSettings.tsx index 02ad6ea30..ee60936f8 100644 --- a/apps/client/src/features/app-settings/panel/general-panel/ViewSettingsForm.tsx +++ b/apps/client/src/features/app-settings/panel/settings-panel/ViewSettings.tsx @@ -1,26 +1,26 @@ import { useEffect } from 'react'; import { Controller, useForm } from 'react-hook-form'; -import { Button, Input, Switch, useDisclosure } from '@chakra-ui/react'; -import { ViewSettings } from 'ontime-types'; +import { Switch } from '@chakra-ui/react'; +import { useDisclosure } from '@mantine/hooks'; +import { ViewSettings as ViewSettingsType } from 'ontime-types'; import { maybeAxiosError } from '../../../../common/api/utils'; +import Button from '../../../../common/components/buttons/Button'; import Info from '../../../../common/components/info/Info'; import { SwatchPickerRHF } from '../../../../common/components/input/colour-input/SwatchPicker'; +import Input from '../../../../common/components/input/input/Input'; import ExternalLink from '../../../../common/components/link/external-link/ExternalLink'; -import useInfo from '../../../../common/hooks-query/useInfo'; import useViewSettings from '../../../../common/hooks-query/useViewSettings'; import { preventEscape } from '../../../../common/utils/keyEvent'; -import { isOntimeCloud } from '../../../../externals'; import * as Panel from '../../panel-utils/PanelUtils'; -import CodeEditorModal from './StyleEditorModal'; +import CodeEditorModal from './composite/StyleEditorModal'; const cssOverrideDocsUrl = 'https://docs.getontime.no/features/custom-styling/'; -export default function ViewSettingsForm() { +export default function ViewSettings() { const { data, isPending, mutateAsync } = useViewSettings(); - const { data: info, status: infoStatus } = useInfo(); - const { isOpen: isCodeEditorOpen, onOpen: onCodeEditorOpen, onClose: onCodeEditorClose } = useDisclosure(); + const [isCodeEditorOpen, codeEditorHandler] = useDisclosure(); const { control, @@ -29,7 +29,7 @@ export default function ViewSettingsForm() { register, reset, formState: { isSubmitting, isDirty, errors }, - } = useForm({ + } = useForm({ defaultValues: data, values: data, resetOptions: { @@ -44,7 +44,7 @@ export default function ViewSettingsForm() { } }, [data, reset]); - const onSubmit = async (formData: ViewSettings) => { + const onSubmit = async (formData: ViewSettingsType) => { try { mutateAsync(formData); } catch (error) { @@ -61,8 +61,6 @@ export default function ViewSettingsForm() { return null; } - const isLoading = isPending || infoStatus === 'pending'; - return ( View settings - -
    - You can the Ontime views or customise its styles by modifying the provided CSS file. + You can customise the styles applied to Ontime views by providing overriding CSS rules.
    - {!isOntimeCloud && ( - <> -
    - The loaded CSS file is in the user directory at{' '} - {`${info.publicDir}/user/styles/override.css`} -
    - - )} See the docs
    - + {errors.root?.message} - + )} /> - @@ -158,11 +142,8 @@ export default function ViewSettingsForm() { description='Message for negative timers; applies only if the timer isn`t frozen on End. If no message is provided, it continues into negative time' /> diff --git a/apps/client/src/features/app-settings/panel/general-panel/GeneralPinInput.tsx b/apps/client/src/features/app-settings/panel/settings-panel/composite/GeneralPinInput.tsx similarity index 95% rename from apps/client/src/features/app-settings/panel/general-panel/GeneralPinInput.tsx rename to apps/client/src/features/app-settings/panel/settings-panel/composite/GeneralPinInput.tsx index c32c99f4c..5540beaed 100644 --- a/apps/client/src/features/app-settings/panel/general-panel/GeneralPinInput.tsx +++ b/apps/client/src/features/app-settings/panel/settings-panel/composite/GeneralPinInput.tsx @@ -4,7 +4,7 @@ import { IoEyeOutline } from 'react-icons/io5'; import { IconButton, Input, InputGroup, InputRightElement } from '@chakra-ui/react'; import { Settings } from 'ontime-types'; -import { isAlphanumeric } from '../../../../common/utils/regex'; +import { isAlphanumeric } from '../../../../../common/utils/regex'; interface GeneralPinInputProps { register: UseFormRegister; diff --git a/apps/client/src/features/app-settings/panel/general-panel/StyleEditor.module.scss b/apps/client/src/features/app-settings/panel/settings-panel/composite/StyleEditor.module.scss similarity index 100% rename from apps/client/src/features/app-settings/panel/general-panel/StyleEditor.module.scss rename to apps/client/src/features/app-settings/panel/settings-panel/composite/StyleEditor.module.scss diff --git a/apps/client/src/features/app-settings/panel/general-panel/StyleEditor.tsx b/apps/client/src/features/app-settings/panel/settings-panel/composite/StyleEditor.tsx similarity index 100% rename from apps/client/src/features/app-settings/panel/general-panel/StyleEditor.tsx rename to apps/client/src/features/app-settings/panel/settings-panel/composite/StyleEditor.tsx diff --git a/apps/client/src/features/app-settings/panel/general-panel/StyleEditorModal.module.scss b/apps/client/src/features/app-settings/panel/settings-panel/composite/StyleEditorModal.module.scss similarity index 100% rename from apps/client/src/features/app-settings/panel/general-panel/StyleEditorModal.module.scss rename to apps/client/src/features/app-settings/panel/settings-panel/composite/StyleEditorModal.module.scss diff --git a/apps/client/src/features/app-settings/panel/general-panel/StyleEditorModal.tsx b/apps/client/src/features/app-settings/panel/settings-panel/composite/StyleEditorModal.tsx similarity index 91% rename from apps/client/src/features/app-settings/panel/general-panel/StyleEditorModal.tsx rename to apps/client/src/features/app-settings/panel/settings-panel/composite/StyleEditorModal.tsx index bbe3fb0c5..d99e33193 100644 --- a/apps/client/src/features/app-settings/panel/general-panel/StyleEditorModal.tsx +++ b/apps/client/src/features/app-settings/panel/settings-panel/composite/StyleEditorModal.tsx @@ -1,10 +1,10 @@ import { lazy, useEffect, useRef, useState } from 'react'; -import { getCSSContents, postCSSContents, restoreCSSContents } from '../../../../common/api/assets'; -import Button from '../../../../common/components/buttons/Button'; -import Info from '../../../../common/components/info/Info'; -import Modal from '../../../../common/components/modal/Modal'; -import * as Panel from '../../panel-utils/PanelUtils'; +import { getCSSContents, postCSSContents, restoreCSSContents } from '../../../../../common/api/assets'; +import Button from '../../../../../common/components/buttons/Button'; +import Info from '../../../../../common/components/info/Info'; +import Modal from '../../../../../common/components/modal/Modal'; +import * as Panel from '../../../panel-utils/PanelUtils'; import style from './StyleEditorModal.module.scss'; diff --git a/apps/client/src/features/app-settings/panel/general-panel/prismjs.d.ts b/apps/client/src/features/app-settings/panel/settings-panel/composite/prismjs.d.ts similarity index 100% rename from apps/client/src/features/app-settings/panel/general-panel/prismjs.d.ts rename to apps/client/src/features/app-settings/panel/settings-panel/composite/prismjs.d.ts diff --git a/apps/client/src/features/app-settings/panel/shutdown-panel/ShutdownPanel.tsx b/apps/client/src/features/app-settings/panel/shutdown-panel/ShutdownPanel.tsx index e6b203b54..b491a611c 100644 --- a/apps/client/src/features/app-settings/panel/shutdown-panel/ShutdownPanel.tsx +++ b/apps/client/src/features/app-settings/panel/shutdown-panel/ShutdownPanel.tsx @@ -1,27 +1,20 @@ import { useRef } from 'react'; -import { - AlertDialog, - AlertDialogBody, - AlertDialogContent, - AlertDialogFooter, - AlertDialogHeader, - AlertDialogOverlay, - Button, - useDisclosure, -} from '@chakra-ui/react'; +import { useDisclosure } from '@mantine/hooks'; +import Button from '../../../../common/components/buttons/Button'; +import Dialog from '../../../../common/components/dialog/Dialog'; import { useElectronEvent } from '../../../../common/hooks/useElectronEvent'; import { isLocalhost, isOntimeCloud } from '../../../../externals'; import * as Panel from '../../panel-utils/PanelUtils'; export default function ShutdownPanel() { const { isElectron, sendToElectron } = useElectronEvent(); - const { isOpen, onOpen, onClose } = useDisclosure(); + const [isOpen, handler] = useDisclosure(); const cancelRef = useRef(null); const sendShutdown = () => { sendToElectron('shutdown', 'now'); - onClose(); + handler.close(); }; const canShutdown = isElectron || isLocalhost; @@ -40,32 +33,33 @@ export default function ShutdownPanel() { The runtime state will be lost, but your project is kept for next time. )} - {!canShutdown && ( Note: Ontime can only be shutdown from the machine it is running in. )} - - - - - Ontime Shutdown - - - This will shutdown the Ontime server.
    Are you sure? -
    - - - - -
    -
    -
    + + This will shutdown the Ontime server.
    Are you sure? + + } + footerElements={ + <> + + + + } + />
    ); diff --git a/apps/client/src/features/app-settings/useAppSettingsMenu.tsx b/apps/client/src/features/app-settings/useAppSettingsMenu.tsx index c9fcbd957..f98939840 100644 --- a/apps/client/src/features/app-settings/useAppSettingsMenu.tsx +++ b/apps/client/src/features/app-settings/useAppSettingsMenu.tsx @@ -11,61 +11,63 @@ export type SettingsOption = { }; const staticOptions = [ + { + id: 'settings', + label: 'Settings', + secondary: [ + { id: 'settings__data', label: 'Project data' }, + { id: 'settings__general', label: 'General settings' }, + { id: 'settings__view', label: 'View settings' }, + ], + }, { id: 'project', label: 'Project', + split: true, secondary: [ { id: 'project__create', label: 'Create...' }, - { id: 'project__data', label: 'Project data' }, - { id: 'project__rundowns', label: 'Manage rundowns' }, { id: 'project__list', label: 'Manage projects' }, ], }, { - id: 'general', - label: 'App Settings', + id: 'manage', + label: 'Project data', secondary: [ - { id: 'general__settings', label: 'General settings' }, - { id: 'general__editor', label: 'Editor settings' }, - { id: 'general__view', label: 'View settings' }, + { id: 'manage__defaults', label: 'Rundown defaults' }, + { id: 'manage__custom', label: 'Custom fields' }, + { id: 'manage__rundowns', label: 'Manage rundowns' }, + { id: 'manage__sheets', label: 'Import spreadsheet' }, + { id: 'manage__sheets', label: 'Sync with Google Sheet' }, ], }, - { - id: 'feature_settings', - label: 'Feature Settings', - secondary: [ - { id: 'feature_settings__custom', label: 'Custom fields' }, - { id: 'feature_settings__urlpresets', label: 'URL Presets' }, - { id: 'feature_settings__report', label: 'Report' }, - ], - }, - { - id: 'sources', - label: 'Data Sources', - secondary: [ - { id: 'sources__xlsx', label: 'Import spreadsheet' }, - { id: 'sources__gsheet', label: 'Sync with Google Sheet' }, - ], - split: true, - }, { id: 'automation', label: 'Automation', + split: true, secondary: [ { id: 'automation__settings', label: 'Automation settings' }, { id: 'automation__automations', label: 'Manage automations' }, { id: 'automation__triggers', label: 'Manage triggers' }, ], }, + { + id: 'sharing', + label: 'Sharing and reporting', + split: true, + secondary: [ + { id: 'sharing__presets', label: 'URL Presets' }, + { + id: 'sharing__link', + label: 'Share link', + }, + { id: 'sharing__report', label: 'Runtime report' }, + ], + }, { id: 'network', label: 'Network', split: true, secondary: [ - { - id: 'network__link', - label: 'Share link', - }, { id: 'network__log', label: 'Event log', diff --git a/apps/client/src/features/control/message/InputRow.tsx b/apps/client/src/features/control/message/InputRow.tsx index 23bdf59cc..76cc2f232 100644 --- a/apps/client/src/features/control/message/InputRow.tsx +++ b/apps/client/src/features/control/message/InputRow.tsx @@ -1,6 +1,6 @@ import { PropsWithChildren, useEffect, useRef, useState } from 'react'; -import { Input } from '@chakra-ui/react'; +import Input from '../../../common/components/input/input/Input'; import { cx } from '../../../common/utils/styleUtils'; import style from './InputRow.module.scss'; @@ -47,15 +47,7 @@ export default function InputRow(props: PropsWithChildren) { {label}
    - + {children}
    diff --git a/apps/client/src/features/operator/edit-modal/EditModal.tsx b/apps/client/src/features/operator/edit-modal/EditModal.tsx index 1bfd9aaf0..86045b4e5 100644 --- a/apps/client/src/features/operator/edit-modal/EditModal.tsx +++ b/apps/client/src/features/operator/edit-modal/EditModal.tsx @@ -1,11 +1,11 @@ import { Fragment, useRef, useState } from 'react'; import { IoClose } from 'react-icons/io5'; import { Dialog } from '@base-ui-components/react/dialog'; -import { Textarea } from '@chakra-ui/react'; import { OntimeEvent } from 'ontime-types'; import Button from '../../../common/components/buttons/Button'; import IconButton from '../../../common/components/buttons/IconButton'; +import Textarea from '../../../common/components/input/textarea/Textarea'; import { useEntryActions } from '../../../common/hooks/useEntryAction'; import { EditEvent } from '../operator.types'; @@ -74,11 +74,10 @@ export default function EditModal(props: EditModalProps) { ref={(element) => { if (element) inputRef.current.push(element); }} - variant='ontime-filled' placeholder={`Add value for ${field.label} field`} defaultValue={field.value} data-field={field.id} - isDisabled={loading} + disabled={loading} resize='none' rows={5} /> diff --git a/apps/client/src/features/rundown/Rundown.tsx b/apps/client/src/features/rundown/Rundown.tsx index 5698a9b01..99c865f71 100644 --- a/apps/client/src/features/rundown/Rundown.tsx +++ b/apps/client/src/features/rundown/Rundown.tsx @@ -435,9 +435,9 @@ export default function Rundown({ data }: RundownProps) { * Outside a block, the value will be undefined * If the colour is empty string '' * ie: we are inside a block, but there is no defined colour - * we default to $gray-1050 #303030 + * we default to $gray-500 #9d9d9d */ - const blockColour = rundownMetadata.groupColour === '' ? '#303030' : rundownMetadata.groupColour; + const blockColour = rundownMetadata.groupColour === '' ? '#9d9d9d' : rundownMetadata.groupColour; return ( diff --git a/apps/client/src/features/rundown/common/EditableBlockTitle.tsx b/apps/client/src/features/rundown/common/EditableBlockTitle.tsx index 93a0e0699..513bbb800 100644 --- a/apps/client/src/features/rundown/common/EditableBlockTitle.tsx +++ b/apps/client/src/features/rundown/common/EditableBlockTitle.tsx @@ -1,6 +1,6 @@ import { useCallback, useRef } from 'react'; -import { Input } from '@chakra-ui/react'; +import Input from '../../../common/components/input/input/Input'; import useReactiveTextInput from '../../../common/components/input/text-input/useReactiveTextInput'; import { useEntryActions } from '../../../common/hooks/useEntryAction'; import { cx } from '../../../common/utils/styleUtils'; @@ -39,7 +39,8 @@ export default function EditableBlockTitle(props: TitleEditorProps) { return ( ); } diff --git a/apps/client/src/features/rundown/placements/FinderPlacement.tsx b/apps/client/src/features/rundown/placements/FinderPlacement.tsx index 22e397275..dc082a88b 100644 --- a/apps/client/src/features/rundown/placements/FinderPlacement.tsx +++ b/apps/client/src/features/rundown/placements/FinderPlacement.tsx @@ -1,21 +1,20 @@ import { memo } from 'react'; -import { useDisclosure } from '@chakra-ui/react'; -import { useHotkeys } from '@mantine/hooks'; +import { useDisclosure, useHotkeys } from '@mantine/hooks'; import Finder from '../../../views/editor/finder/Finder'; export default memo(FinderPlacement); function FinderPlacement() { - const { isOpen, onToggle, onClose } = useDisclosure(); + const [isOpen, handler] = useDisclosure(); useHotkeys([ - ['mod + f', onToggle], - ['Escape', onClose], + ['mod + f', handler.toggle], + ['Escape', handler.close], ]); if (isOpen) { - return ; + return ; } return null; diff --git a/apps/client/src/features/rundown/quick-add-block/QuickAddBlock.tsx b/apps/client/src/features/rundown/quick-add-block/QuickAddBlock.tsx index 85eb32dfe..66fe499f9 100644 --- a/apps/client/src/features/rundown/quick-add-block/QuickAddBlock.tsx +++ b/apps/client/src/features/rundown/quick-add-block/QuickAddBlock.tsx @@ -59,9 +59,9 @@ function QuickAddBlock({ previousEventId, parentBlock, backgroundColor }: QuickA /** * If the colour is empty string '' * ie: we are inside a block, but there is no defined colour - * we default to $gray-1050 #303030 + * we default to $gray-500 #9d9d9d */ - const blockColour = backgroundColor === '' ? '#303030' : backgroundColor; + const blockColour = backgroundColor === '' ? '#9d9d9d' : backgroundColor; return (
    diff --git a/apps/client/src/features/rundown/rundown-block/RundownBlock.module.scss b/apps/client/src/features/rundown/rundown-block/RundownBlock.module.scss index a9ad86a5d..c43aff0dc 100644 --- a/apps/client/src/features/rundown/rundown-block/RundownBlock.module.scss +++ b/apps/client/src/features/rundown/rundown-block/RundownBlock.module.scss @@ -51,6 +51,7 @@ display: flex; gap: 3rem; margin-bottom: 0.25rem; + white-space: nowrap; } .metaEntry { diff --git a/apps/client/src/features/rundown/rundown-block/RundownBlock.tsx b/apps/client/src/features/rundown/rundown-block/RundownBlock.tsx index 450a04965..8fff87166 100644 --- a/apps/client/src/features/rundown/rundown-block/RundownBlock.tsx +++ b/apps/client/src/features/rundown/rundown-block/RundownBlock.tsx @@ -7,11 +7,11 @@ import { IoReorderTwo, IoTrash, } from 'react-icons/io5'; -import { IconButton } from '@chakra-ui/react'; import { useSortable } from '@dnd-kit/sortable'; import { CSS } from '@dnd-kit/utilities'; import { EntryId, OntimeBlock } from 'ontime-types'; +import IconButton from '../../../common/components/buttons/IconButton'; import { useContextMenu } from '../../../common/hooks/useContextMenu'; import { useEntryActions } from '../../../common/hooks/useEntryAction'; import { cx, getAccessibleColour } from '../../../common/utils/styleUtils'; @@ -120,13 +120,7 @@ export default function RundownBlock({ data, hasCursor, collapsed, onCollapse }:
    - onCollapse(!collapsed, data.id)} - color='#e2e2e2' // $gray-200 - variant='ontime-ghosted' - size='sm' - > + onCollapse(!collapsed, data.id)}> {collapsed ? : }
    diff --git a/apps/client/src/features/rundown/rundown-delay/RundownDelay.tsx b/apps/client/src/features/rundown/rundown-delay/RundownDelay.tsx index 91f6f7762..1812e1b62 100644 --- a/apps/client/src/features/rundown/rundown-delay/RundownDelay.tsx +++ b/apps/client/src/features/rundown/rundown-delay/RundownDelay.tsx @@ -1,10 +1,10 @@ import { useEffect, useRef } from 'react'; import { IoCheckmarkDone, IoClose, IoReorderTwo } from 'react-icons/io5'; -import { Button } from '@chakra-ui/react'; import { useSortable } from '@dnd-kit/sortable'; import { CSS } from '@dnd-kit/utilities'; import { OntimeDelay } from 'ontime-types'; +import Button from '../../../common/components/buttons/Button'; import DelayInput from '../../../common/components/input/delay-input/DelayInput'; import { useEntryActions } from '../../../common/hooks/useEntryAction'; import { cx } from '../../../common/utils/styleUtils'; @@ -64,10 +64,11 @@ export default function RundownDelay({ data, hasCursor }: RundownDelayProps) {
    - -
    diff --git a/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/BlockRow.tsx b/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/BlockRow.tsx index 9f850946c..a16304c48 100644 --- a/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/BlockRow.tsx +++ b/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/BlockRow.tsx @@ -30,7 +30,7 @@ export default function BlockRow({ blockId, colour, hidePast, rowId, rowIndex, t } return ( - + {showActionMenu && ( {delayTime} diff --git a/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/EventRow.tsx b/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/EventRow.tsx index ada14ced8..246d315a2 100644 --- a/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/EventRow.tsx +++ b/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/EventRow.tsx @@ -84,6 +84,7 @@ export default function EventRow({ '--user-bg': parentBgColour ?? 'transparent', }} ref={selectedRef ?? ownRef} + data-testid='cuesheet-event' > {showActionMenu && ( diff --git a/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-settings/CuesheetShareModal.tsx b/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-settings/CuesheetShareModal.tsx index 996cadc29..7b27904a3 100644 --- a/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-settings/CuesheetShareModal.tsx +++ b/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-settings/CuesheetShareModal.tsx @@ -5,7 +5,7 @@ import RotatedLink from '../../../../common/components/icons/RotatedLink'; import Modal from '../../../../common/components/modal/Modal'; import useInfo from '../../../../common/hooks-query/useInfo'; import useUrlPresets from '../../../../common/hooks-query/useUrlPresets'; -import GenerateLinkFormExport from '../../../../features/app-settings/panel/network-panel/GenerateLinkFormExport'; +import GenerateLinkFormExport from '../../../../features/app-settings/panel/feature-panel/GenerateLinkFormExport'; function CuesheetShareModal() { const { data: infoData } = useInfo(); diff --git a/apps/client/src/views/editor/Editor.tsx b/apps/client/src/views/editor/Editor.tsx index f5c7d9831..e862d6590 100644 --- a/apps/client/src/views/editor/Editor.tsx +++ b/apps/client/src/views/editor/Editor.tsx @@ -40,7 +40,7 @@ export default function Editor() { if (isSettingsOpen) { close(); } else { - setLocation('project'); + setLocation('settings'); } }, [close, isSettingsOpen, setLocation]); @@ -54,12 +54,7 @@ export default function Editor() { - + {isSettingsOpen ? : } diff --git a/apps/client/src/views/editor/welcome/Welcome.tsx b/apps/client/src/views/editor/welcome/Welcome.tsx index d787b7f91..55474b032 100644 --- a/apps/client/src/views/editor/welcome/Welcome.tsx +++ b/apps/client/src/views/editor/welcome/Welcome.tsx @@ -74,7 +74,7 @@ export default function Welcome({ onClose }: WelcomeProps) {
    Welcome to Ontime - +
    diff --git a/apps/client/src/views/editor/welcome/composite/ImportProjectButton.tsx b/apps/client/src/views/editor/welcome/composite/ImportProjectButton.tsx index 1863479d3..53422c856 100644 --- a/apps/client/src/views/editor/welcome/composite/ImportProjectButton.tsx +++ b/apps/client/src/views/editor/welcome/composite/ImportProjectButton.tsx @@ -4,7 +4,6 @@ */ import { ChangeEvent, useRef } from 'react'; -import { Input } from '@chakra-ui/react'; import { uploadProjectFile } from '../../../../common/api/db'; import { invalidateAllCaches } from '../../../../common/api/utils'; @@ -41,7 +40,7 @@ export default function ImportProjectButton({ onFinish }: ImportProjectButtonPro return ( <> - { await page.goto('http://localhost:4001/editor'); - if (await page.getByText('Welcome to Ontime')) { - await page.getByRole('button', { name: 'Close' }).click(); + // Try to close welcome modal if it appears (times out silently if not present) + try { + await page.getByText('Welcome to Ontime').waitFor({ timeout: 1000 }); + await page.getByRole('button', { name: 'close welcome modal' }).click(); + } catch { + // Modal wasn't shown, continue with the test } await page.getByRole('button', { name: 'Edit' }).click(); diff --git a/e2e/tests/features/202-cuesheet.spec.ts b/e2e/tests/features/202-cuesheet.spec.ts index 3f5bcb652..36f4984a5 100644 --- a/e2e/tests/features/202-cuesheet.spec.ts +++ b/e2e/tests/features/202-cuesheet.spec.ts @@ -9,6 +9,6 @@ test('cuesheet displays events', async ({ page }) => { await expect(page.locator('#cuesheet')).toBeVisible(); // there should be 16 rows in the table (same as the amount of events in the rundown) - const rowCount = await page.locator('#cuesheet tbody tr').count(); - expect(rowCount).toBe(16); + await expect(page.getByTestId('cuesheet-event')).toHaveCount(14); + await expect(page.getByTestId('cuesheet-block')).toHaveCount(2); }); diff --git a/e2e/tests/features/206-url-preset.spec.ts b/e2e/tests/features/206-url-preset.spec.ts index ba86fb054..70311f72a 100644 --- a/e2e/tests/features/206-url-preset.spec.ts +++ b/e2e/tests/features/206-url-preset.spec.ts @@ -5,11 +5,9 @@ test('URL preset feature, it should redirect to given URL', async ({ page }) => // open settings await page.getByRole('button', { name: 'Toggle settings' }).click(); - await page.getByRole('button', { name: 'Feature Settings' }).click(); + await page.getByRole('button', { name: 'URL Presets' }).click(); // create preset - await page.getByTestId('url-preset-form').scrollIntoViewIfNeeded(); - await page.getByTestId('url-preset-form').getByRole('button', { name: 'New' }).scrollIntoViewIfNeeded(); await page.getByTestId('url-preset-form').getByRole('button', { name: 'New' }).click();