From 1849b4d39ffe1f5cfac134e7df33ee0245490237 Mon Sep 17 00:00:00 2001 From: Carlos Valente <34649812+cpvalente@users.noreply.github.com> Date: Sun, 8 Mar 2026 16:22:12 +0100 Subject: [PATCH] Deps migration (#1988) * chore: migrate eslint to oxlint * chore: migrate prettier to oxfmt * chore: migrate typescript * chore: toThrow should have a expected value * chore: cast test value as Day * chore: small title fix * chore: mocks should be hoisted * chore: incorrect async useage * chore: test should be inside description * chore: test sohuld include an expeced * chore: oxfmt --------- Co-authored-by: alex-Arc --- .dockerignore | 4 +- .eslintignore | 2 - .eslintrc | 53 - .github/FUNDING.yml | 2 +- .github/workflows/build_docker.yml | 2 +- .gitignore | 3 +- .oxfmtrc.json | 25 + .oxlintrc.json | 37 + .prettierignore | 14 - .prettierrc | 9 - DEVELOPMENT.md | 46 +- README.md | 8 +- SPONSOR.md | 5 + apps/cli/.eslintrc | 16 - apps/cli/.oxlintrc.json | 5 + apps/cli/.prettierrc | 9 - apps/cli/README.md | 10 +- apps/cli/package.json | 47 +- apps/client/.eslintignore | 2 - apps/client/.eslintrc | 142 - apps/client/.oxlintrc.json | 5 + apps/client/.prettierrc | 9 - apps/client/package.json | 16 +- apps/client/public/site.webmanifest | 4 +- apps/client/src/App.tsx | 7 +- apps/client/src/AppRouter.tsx | 10 +- apps/client/src/common/api/assets.ts | 3 +- apps/client/src/common/api/external.ts | 1 - apps/client/src/common/api/report.ts | 3 +- apps/client/src/common/api/sheets.ts | 12 +- .../common/components/checkbox/Checkbox.tsx | 2 +- .../client-modal/RedirectClientModal.tsx | 2 +- .../src/common/components/dialog/Dialog.tsx | 2 +- .../components/dropdown-menu/DropdownMenu.tsx | 2 +- .../error-boundary/ErrorBoundary.jsx | 4 +- .../identify-overlay/IdentifyOverlay.tsx | 2 +- .../input/auto-textarea/AutoTextarea.tsx | 2 +- .../input/colour-input/SwatchPicker.tsx | 4 +- .../common/components/input/input/Input.tsx | 2 +- .../input/popover-picker/PopoverPicker.tsx | 2 +- .../input/text-input/useReactiveTextInput.tsx | 2 +- .../components/input/textarea/Textarea.tsx | 2 +- .../input/time-input/NullableTimeInput.tsx | 2 +- .../components/input/time-input/TimeInput.tsx | 2 +- .../external-link/ExternalLink.module.scss | 4 +- .../common/components/modal/Modal.module.scss | 2 +- .../src/common/components/modal/Modal.tsx | 2 +- .../navigation-menu/NavigationMenu.tsx | 5 +- .../navigation-menu/ViewNavigationMenu.tsx | 5 +- .../NavigationMenuItem.tsx | 4 +- .../components/popover/Popover.module.scss | 3 +- .../src/common/components/popover/Popover.tsx | 2 +- .../components/protect-route/ProtectRoute.tsx | 1 - .../scroll-area/ScrollArea.module.scss | 2 +- .../components/scroll-area/ScrollArea.tsx | 2 +- .../src/common/components/select/Select.tsx | 2 +- .../common/components/state/Empty.module.scss | 2 +- .../components/switch/Switch.module.scss | 4 +- .../components/tooltip/Tooltip.module.scss | 2 +- .../src/common/components/tooltip/Tooltip.tsx | 2 +- .../view-params-editor/ParamInput.tsx | 3 +- .../view-params-editor/ViewParamsEditor.tsx | 7 +- .../view-params-editor/ViewParamsPresets.tsx | 2 +- .../ViewParamsSection.module.scss | 2 +- .../view-params-editor/ViewParamsSection.tsx | 3 +- .../view-params-editor/viewParams.utils.ts | 1 - apps/client/src/common/context/AppContext.tsx | 2 +- .../common/context/EntryActionsContext.tsx | 2 +- .../src/common/context/PresetContext.tsx | 2 +- .../src/common/hooks-query/useAppVersion.ts | 2 +- .../src/common/hooks-query/useProjectList.ts | 2 +- .../common/hooks-query/useProjectRundowns.ts | 13 +- .../src/common/hooks-query/useRundown.ts | 2 +- .../src/common/hooks-query/useUrlPresets.ts | 2 +- apps/client/src/common/hooks/useClientPath.ts | 3 +- .../client/src/common/hooks/useEntryAction.ts | 10 +- .../src/common/hooks/useFollowComponent.ts | 2 +- .../hooks/useHorizontalFollowComponent.ts | 2 +- .../src/common/hooks/useIsMobileDevice.ts | 2 +- .../src/common/hooks/useIsMobileScreen.ts | 2 +- .../src/common/hooks/useIsSmallDevice.ts | 2 +- .../src/common/hooks/useIsSmallScreen.ts | 2 +- .../src/common/stores/editorSettings.ts | 4 +- apps/client/src/common/stores/logger.ts | 2 +- apps/client/src/common/stores/runtime.ts | 2 +- .../utils/__tests__/styleUtils.module.scss | 6 +- .../src/common/utils/__tests__/time.test.ts | 8 +- .../common/utils/__tests__/urlPresets.test.ts | 6 +- apps/client/src/common/utils/dateConfig.ts | 2 +- apps/client/src/common/utils/linkUtils.ts | 12 +- .../src/common/utils/rundownMetadata.ts | 10 +- apps/client/src/common/utils/time.ts | 5 +- apps/client/src/common/utils/urlPresets.ts | 2 +- apps/client/src/declarations/declaration.d.ts | 5 + apps/client/src/externals.ts | 2 +- .../src/features/app-settings/AppSettings.tsx | 5 +- .../app-settings/panel-list/PanelList.tsx | 8 +- .../panel/about-panel/AboutPanel.tsx | 1 - .../automations-panel/AutomationForm.tsx | 17 +- .../automations-panel/AutomationPanel.tsx | 3 +- .../automations-panel/AutomationsList.tsx | 3 +- .../automations-panel/OntimeActionForm.tsx | 2 +- .../panel/automations-panel/TriggerForm.tsx | 3 +- .../panel/automations-panel/TriggersList.tsx | 3 +- .../automations-panel/TriggersListItem.tsx | 3 +- .../template-input/TemplateInput.tsx | 3 +- .../panel/feature-panel/FeaturePanel.tsx | 1 - .../panel/feature-panel/ReportSettings.tsx | 1 - .../panel/feature-panel/URLPresets.tsx | 3 +- .../composite/URLPresetForm.module.scss | 2 +- .../feature-panel/composite/URLPresetForm.tsx | 2 +- .../feature-panel/reportSettings.utils.ts | 2 +- .../panel/manage-panel/CustomFields.tsx | 3 +- .../panel/manage-panel/ManagePanel.tsx | 3 +- .../panel/manage-panel/ManageRundowns.tsx | 3 +- .../manage-panel/RundownDefaultSettings.tsx | 2 +- .../composite/CustomFieldEntry.tsx | 3 +- .../composite/CustomFieldForm.tsx | 4 +- .../composite/RundownRenameForm.tsx | 2 +- .../manage-panel/sources-panel/GSheetInfo.tsx | 5 +- .../sources-panel/GSheetSetup.tsx | 1 - .../sources-panel/ImportReview.tsx | 3 +- .../sources-panel/SourcesPanel.tsx | 5 +- .../import-map/ImportMapForm.tsx | 5 +- .../__test__/importMapUtils.test.ts | 2 +- .../sources-panel/preview/PreviewRundown.tsx | 4 +- .../sources-panel/useGoogleSheet.ts | 1 - .../sources-panel/useSheetStore.ts | 2 +- .../panel/network-panel/NetworkLogPanel.tsx | 3 +- .../ClientControlPanel.module.scss | 2 +- .../client-control/ClientControlPanel.tsx | 1 - .../client-control/ClientList.tsx | 2 +- .../panel/project-panel/ManageProjects.tsx | 1 - .../panel/project-panel/ProjectList.tsx | 1 - .../panel/project-panel/ProjectListItem.tsx | 1 - .../panel/project-panel/ProjectMergeForm.tsx | 3 +- .../project-panel/ProjectPanel.module.scss | 2 +- .../panel/project-panel/ProjectPanel.tsx | 1 - .../panel/settings-panel/GeneralSettings.tsx | 5 +- .../panel/settings-panel/ProjectData.tsx | 2 +- .../settings-panel/ServerPortSettings.tsx | 2 +- .../panel/settings-panel/SettingsPanel.tsx | 1 - .../panel/settings-panel/ViewSettings.tsx | 5 +- .../composite/CustomTranslationModal.tsx | 2 +- .../composite/GeneralPinInput.tsx | 2 +- .../settings-panel/composite/StyleEditor.tsx | 3 +- .../composite/StyleEditorModal.module.scss | 2 +- .../composite/StyleEditorModal.tsx | 2 +- .../panel/shutdown-panel/ShutdownPanel.tsx | 2 +- .../app-settings/quick-start/QuickStart.tsx | 3 +- .../control/message/MessageControl.tsx | 1 - .../control/message/MessageControlExport.tsx | 1 - .../control/message/TimerPreview.module.scss | 1 - .../features/control/message/TimerPreview.tsx | 4 +- .../message/TimerViewControl.module.scss | 3 +- .../control/message/TimerViewControl.tsx | 3 +- .../control/playback/PlaybackControl.tsx | 1 - .../control/playback/TimerControlExport.tsx | 1 - .../control/playback/add-time/AddTime.tsx | 2 +- .../control/playback/aux-timer/AuxTimer.tsx | 2 +- .../PlaybackButtons.module.scss | 7 +- .../playback-buttons/PlaybackButtons.tsx | 2 +- .../playback/playback-timer/PlaybackTimer.tsx | 4 +- .../control/playback/tap-button/TapButton.tsx | 2 +- .../TrackingPlaybackBar.tsx | 2 +- apps/client/src/features/log/Log.tsx | 14 +- .../client/src/features/operator/Operator.tsx | 5 +- .../src/features/operator/OperatorExport.tsx | 1 - .../CustomFieldEditModal.module.scss | 2 +- .../CustomFieldEditModal.tsx | 4 +- .../follow-button/FollowButton.module.scss | 2 +- .../operator/operator-event/OperatorEvent.tsx | 2 +- .../features/operator/operator.options.tsx | 2 +- .../src/features/operator/operator.utils.ts | 65 +- .../operator/status-bar/StatusBar.tsx | 1 - .../src/features/operator/useOperatorData.ts | 2 +- .../features/overview/CuesheetOverview.tsx | 3 +- .../src/features/overview/EditorOverview.tsx | 3 +- .../src/features/overview/OverviewWrapper.tsx | 2 +- .../composite/TimeElements.module.scss | 4 +- .../overview/composite/TimeElements.tsx | 7 +- .../src/features/rundown/Rundown.module.scss | 2 +- apps/client/src/features/rundown/Rundown.tsx | 15 +- .../src/features/rundown/RundownEmpty.tsx | 2 +- .../src/features/rundown/RundownEntry.tsx | 2 +- .../src/features/rundown/RundownExport.tsx | 3 +- .../src/features/rundown/RundownList.tsx | 3 +- .../entry-editor/CuesheetEventEditor.tsx | 3 +- .../rundown/entry-editor/EventEditor.tsx | 3 +- .../rundown/entry-editor/EventEditorEmpty.tsx | 2 +- .../rundown/entry-editor/GroupEditor.tsx | 3 +- .../rundown/entry-editor/MilestoneEditor.tsx | 3 +- .../entry-editor/RundownEntryEditor.tsx | 3 +- .../composite/EventEditorCustomFields.tsx | 3 +- .../composite/EventEditorTimes.tsx | 4 +- .../composite/EventEditorTitles.tsx | 3 +- .../composite/EventEditorTriggers.module.scss | 2 +- .../composite/EventEditorTriggers.tsx | 5 +- .../composite/TargetDurationInput.tsx | 2 +- .../quick-add-buttons/QuickAddButtons.tsx | 4 +- .../quick-add-cursor/QuickAddInline.tsx | 2 +- .../rundown/hooks/useRundownCommands.ts | 6 +- .../features/rundown/hooks/useRundownDnd.ts | 4 +- .../rundown/hooks/useRundownKeyboard.ts | 2 +- .../rundown/placements/FinderPlacement.tsx | 2 +- .../rundown-delay/DelayInput.module.scss | 2 +- .../rundown/rundown-delay/DelayInput.tsx | 3 +- .../rundown/rundown-delay/RundownDelay.tsx | 5 +- .../rundown-event/RundownEvent.module.scss | 4 +- .../rundown/rundown-event/RundownEvent.tsx | 9 +- .../rundown-event/RundownEventInner.tsx | 3 +- .../composite/RundownEventChip.tsx | 6 +- .../composite/RundownEventPlayback.tsx | 2 +- .../rundown/rundown-group/RundownGroup.tsx | 8 +- .../rundown/rundown-header/RundownHeader.tsx | 3 +- .../rundown-header/RundownHeaderMobile.tsx | 2 +- .../rundown/rundown-header/RundownMenu.tsx | 4 +- .../rundown-milestone/RundownMilestone.tsx | 4 +- .../rundown/rundown-table/RundownTable.tsx | 1 - .../src/features/rundown/rundown.utils.ts | 2 +- .../time-input-flow/TimeInputFlow.module.scss | 2 +- .../rundown/time-input-flow/TimeInputFlow.tsx | 5 +- .../features/rundown/useCollapsedGroups.ts | 2 +- .../src/features/rundown/useEventSelection.ts | 2 +- .../rundown/useSelectAndRevealEntry.ts | 2 +- .../src/features/sharing/GenerateLinkForm.tsx | 5 +- .../sharing/GenerateLinkFormExport.tsx | 3 +- .../composite/CuesheetLinkOptions.module.scss | 2 +- apps/client/src/index.scss | 15 +- apps/client/src/sentry.config.ts | 4 +- apps/client/src/theme/_mixins.scss | 2 +- apps/client/src/theme/_ontimeColours.scss | 142 +- apps/client/src/theme/_ontimeStyles.scss | 12 +- .../src/translation/TranslationProvider.tsx | 5 +- apps/client/src/views/ViewLoader.tsx | 3 +- apps/client/src/views/backstage/Backstage.tsx | 5 +- .../src/views/backstage/backstage.options.ts | 2 +- .../src/views/backstage/useBackstageData.ts | 2 +- .../src/views/common/schedule/Schedule.tsx | 1 - .../views/common/schedule/ScheduleContext.tsx | 5 +- .../views/common/schedule/ScheduleExport.tsx | 2 +- .../views/common/schedule/ScheduleItem.tsx | 1 - .../src/views/common/schedule/ScheduleNav.tsx | 1 - apps/client/src/views/countdown/Countdown.tsx | 3 +- .../src/views/countdown/CountdownSelect.tsx | 3 +- .../countdown/CountdownSubscriptions.tsx | 7 +- .../views/countdown/SingleEventCountdown.tsx | 5 +- .../src/views/countdown/countdown.options.ts | 2 +- .../src/views/countdown/countdown.utils.ts | 2 +- .../src/views/countdown/useCountdownData.ts | 2 +- .../views/cuesheet/CuesheetPage.module.scss | 8 +- .../src/views/cuesheet/CuesheetPage.tsx | 3 +- .../views/cuesheet/CuesheetTableWrapper.tsx | 1 - .../src/views/cuesheet/ProtectedCuesheet.tsx | 1 - .../cuesheet/cuesheet-dnd/CuesheetDnd.tsx | 4 +- .../cuesheet-edit-modal/EntryEditModal.tsx | 1 - .../cuesheet-progress/CuesheetProgress.tsx | 2 +- .../cuesheet/cuesheet-table/CuesheetTable.tsx | 12 +- .../CuesheetHeader.tsx | 5 +- .../cuesheet-table-elements/DurationInput.tsx | 2 +- .../cuesheet-table-elements/EventRow.tsx | 6 +- .../cuesheet-table-elements/GroupRow.tsx | 4 +- .../cuesheet-table-elements/MilestoneRow.tsx | 6 +- .../cuesheet-table-elements/SortableCell.tsx | 2 +- .../cuesheet-table-elements/TextLikeInput.tsx | 2 +- .../cuesheet-table-elements/TimeInput.tsx | 3 +- .../cuesheetColsFactory.tsx | 5 +- .../cuesheet-table-menu/TableMenu.tsx | 3 +- .../CuesheetTableSettings.tsx | 5 +- .../cuesheet-table/useColumnManager.tsx | 2 +- .../src/views/cuesheet/cuesheet.policies.ts | 1 - .../views/cuesheet/useApplyCuesheetPolicy.ts | 3 +- apps/client/src/views/editor/Editor.tsx | 1 - .../src/views/editor/EditorLayoutOptions.tsx | 1 - .../src/views/editor/ProtectedEditor.tsx | 5 +- .../views/editor/finder/Finder.module.scss | 2 +- .../client/src/views/editor/finder/Finder.tsx | 3 +- .../src/views/editor/finder/useFinder.tsx | 2 +- .../src/views/editor/pip-timer/PipHost.tsx | 3 +- .../src/views/editor/pip-timer/PipRoot.tsx | 2 +- .../src/views/editor/pip-timer/PipTimer.scss | 2 +- .../src/views/editor/title-list/TitleList.tsx | 5 +- .../views/editor/title-list/TitleListItem.tsx | 2 +- .../src/views/editor/useEditorLayout.ts | 2 +- .../src/views/editor/welcome/Welcome.tsx | 1 - .../views/editor/welcome/WelcomePlacement.tsx | 1 - .../src/views/project-info/ProjectInfo.scss | 2 +- .../src/views/project-info/ProjectInfo.tsx | 3 +- apps/client/src/views/studio/Studio.tsx | 3 +- apps/client/src/views/studio/StudioClock.tsx | 1 - apps/client/src/views/studio/StudioTimers.tsx | 1 - .../client/src/views/studio/studio.options.ts | 2 +- apps/client/src/views/studio/useStudioData.ts | 2 +- apps/client/src/views/timeline/Timeline.tsx | 7 +- .../src/views/timeline/TimelineEntry.tsx | 29 +- .../src/views/timeline/TimelinePage.tsx | 3 +- .../src/views/timeline/TimelineSections.tsx | 1 - .../timeline-section/TimelineSection.tsx | 2 +- .../src/views/timeline/timeline.options.ts | 2 +- .../src/views/timeline/timeline.utils.ts | 9 +- .../src/views/timeline/useTimelineData.ts | 2 +- apps/client/src/views/timer/Timer.tsx | 3 +- apps/client/src/views/timer/timer.options.ts | 4 +- apps/client/src/views/timer/useTimerData.ts | 2 +- ...{tsconfig.tests.json => tsconfig.app.json} | 29 +- apps/client/tsconfig.json | 44 +- apps/client/tsconfig.vitest.json | 18 + apps/client/vite.config.js | 3 +- apps/electron/.eslintignore | 3 - apps/electron/.eslintrc | 16 - apps/electron/.oxlintrc.json | 5 + apps/electron/package.json | 17 +- apps/electron/src/splash/splash.html | 2 +- apps/resolver/.eslintignore | 2 - apps/resolver/.oxlintrc.json | 5 + apps/resolver/README.md | 4 +- apps/resolver/package.json | 20 +- apps/resolver/tsconfig.dts.json | 6 + apps/resolver/tsconfig.json | 7 +- apps/resolver/tsup.config.js | 8 +- apps/server/.eslintignore | 2 - apps/server/.eslintrc | 12 - apps/server/.oxlintrc.json | 5 + apps/server/.prettierrc | 8 - apps/server/esbuild.js | 33 +- apps/server/package.json | 21 +- apps/server/src/adapters/OscAdapter.ts | 13 +- apps/server/src/adapters/WebsocketAdapter.ts | 20 +- .../src/api-data/assets/assets.router.ts | 9 +- .../src/api-data/assets/assets.service.ts | 4 +- .../__tests__/automation.dao.test.ts | 50 +- .../__tests__/automation.service.test.ts | 56 +- .../__tests__/automation.utils.test.ts | 1 - .../__tests__/automation.validation.test.ts | 77 +- .../automation/__tests__/testUtils.ts | 2 +- .../automation/automation.controller.ts | 6 +- .../src/api-data/automation/automation.dao.ts | 1 - .../api-data/automation/automation.parser.ts | 4 +- .../api-data/automation/automation.router.ts | 10 +- .../api-data/automation/automation.service.ts | 23 +- .../api-data/automation/automation.utils.ts | 8 +- .../automation/automation.validation.ts | 8 +- .../automation/clients/http.client.ts | 3 +- .../automation/clients/ontime.client.ts | 2 +- .../api-data/automation/clients/osc.client.ts | 8 +- .../custom-fields/customFields.parser.ts | 2 +- .../custom-fields/customFields.router.ts | 9 +- .../custom-fields/customFields.validation.ts | 2 +- .../api-data/db/__tests__/db.parser.test.ts | 21 +- apps/server/src/api-data/db/db.controller.ts | 7 +- apps/server/src/api-data/db/db.parser.ts | 13 +- apps/server/src/api-data/db/db.router.ts | 4 +- apps/server/src/api-data/db/db.validation.ts | 1 + .../api-data/db/migration/db.migration.v3.ts | 8 +- .../api-data/db/migration/db.migration.v4.ts | 1 + .../api-data/db/migration/migration.test.ts | 10 +- .../excel/__tests__/excel.parser.test.ts | 5 +- .../excel/__tests__/excel.utils.test.ts | 3 +- .../src/api-data/excel/excel.middleware.ts | 1 - .../server/src/api-data/excel/excel.parser.ts | 19 +- .../server/src/api-data/excel/excel.router.ts | 8 +- .../src/api-data/excel/excel.service.ts | 12 +- apps/server/src/api-data/excel/excel.utils.ts | 2 +- .../src/api-data/excel/excel.validation.ts | 3 +- apps/server/src/api-data/index.ts | 10 +- .../api-data/project-data/projectData.dao.ts | 9 +- .../project-data/projectData.parser.ts | 2 +- .../project-data/projectData.router.ts | 8 +- .../project-data/projectData.validation.ts | 1 + .../src/api-data/report/report.router.ts | 1 + .../src/api-data/report/report.service.ts | 5 +- .../rundown/__mocks__/rundown.mocks.ts | 10 +- .../rundown/__tests__/rundown.dao.test.ts | 43 +- .../rundown/__tests__/rundown.parser.test.ts | 7 +- .../rundown/__tests__/rundown.utils.test.ts | 8 +- .../src/api-data/rundown/rundown.dao.ts | 15 +- .../src/api-data/rundown/rundown.parser.ts | 41 +- .../src/api-data/rundown/rundown.router.ts | 17 +- .../src/api-data/rundown/rundown.service.ts | 23 +- .../src/api-data/rundown/rundown.utils.ts | 20 +- .../api-data/rundown/rundown.validation.ts | 2 +- .../src/api-data/session/session.router.ts | 5 +- .../src/api-data/session/session.service.ts | 12 +- .../api-data/session/session.validation.ts | 1 + .../__tests__/settings.parser.test.ts | 2 +- .../src/api-data/settings/settings.router.ts | 93 +- .../api-data/settings/settings.validation.ts | 1 + .../sheets/__tests__/sheet.utils.test.ts | 16 +- .../src/api-data/sheets/sheets.controller.ts | 13 +- .../src/api-data/sheets/sheets.service.ts | 21 +- .../src/api-data/sheets/sheets.utils.ts | 6 +- .../src/api-data/sheets/sheets.validation.ts | 4 +- .../api-data/url-presets/urlPresets.router.ts | 5 +- .../url-presets/urlPresets.validation.ts | 3 +- .../validation-utils/validationFunction.ts | 6 +- .../view-settings/viewSettings.router.ts | 6 +- .../view-settings/viewSettings.validation.ts | 1 + .../__test__/integration.utils.test.ts | 281 +- .../api-integration/integration.controller.ts | 11 +- .../src/api-integration/integration.router.ts | 12 +- apps/server/src/app.ts | 68 +- apps/server/src/classes/Logger.ts | 4 +- .../src/classes/data-provider/DataProvider.ts | 28 +- .../__tests__/DataProvider.utils.test.ts | 3 +- .../src/classes/port-manager/PortManager.ts | 45 +- apps/server/src/external/README.md | 3 +- apps/server/src/external/demo/index.html | 220 +- apps/server/src/externals.ts | 2 +- apps/server/src/html/login.html | 4 +- apps/server/src/index.ts | 4 +- .../lib/time-core/__tests__/timeCore.test.ts | 2 +- apps/server/src/lib/time-core/timeCore.ts | 2 +- apps/server/src/middleware/authenticate.ts | 10 +- apps/server/src/middleware/noop.ts | 2 +- apps/server/src/middleware/staticGZip.ts | 3 +- apps/server/src/models/dataModel.ts | 3 +- .../src/services/__tests__/rollUtils.test.ts | 32 +- .../src/services/__tests__/timerUtils.test.ts | 24 +- .../app-state-service/AppStateService.ts | 4 +- .../aux-timer-service/AuxTimerService.ts | 2 +- .../message-service/message.service.ts | 2 +- .../project-service/ProjectService.ts | 30 +- .../__tests__/ProjectService.test.ts | 1 - .../project-service/projectServiceUtils.ts | 4 +- .../__tests__/restore.parser.test.ts | 7 +- .../__tests__/restore.service.test.ts | 18 +- .../restore-service/restore.parser.ts | 1 - .../restore-service/restore.service.ts | 3 +- .../services/restore-service/restore.type.ts | 2 +- apps/server/src/services/rollUtils.ts | 4 +- .../runtime-service/runtime.service.ts | 23 +- .../services/runtime-service/runtime.utils.ts | 11 +- apps/server/src/services/timerUtils.ts | 2 +- apps/server/src/setup/index.ts | 4 +- apps/server/src/setup/loadDemo.ts | 2 +- apps/server/src/setup/loadOntimeLogo.ts | 6 +- apps/server/src/setup/loadStyles.ts | 1 - apps/server/src/setup/loadTranslations.ts | 3 +- apps/server/src/stores/EventStore.ts | 2 +- .../stores/__mocks__/runtimeState.mocks.ts | 7 +- .../stores/__mocks__/runtimeStore.mocks.ts | 2 +- .../src/stores/__tests__/runtimeState.test.ts | 57 +- apps/server/src/stores/runtimeState.ts | 20 +- .../src/utils/__tests__/coerceType.test.ts | 4 +- .../utils/__tests__/fileManagement.test.ts | 3 +- apps/server/src/utils/__tests__/time.test.ts | 1 + apps/server/src/utils/development.ts | 1 - apps/server/src/utils/fileManagement.ts | 5 +- apps/server/src/utils/generateCrashReport.ts | 9 +- apps/server/src/utils/time.ts | 2 +- apps/server/src/utils/upload.ts | 6 +- apps/server/test-db/README.md | 3 +- apps/server/tsconfig.app.json | 26 + apps/server/tsconfig.json | 27 +- apps/server/tsconfig.tests.json | 21 - apps/server/tsconfig.vitest.json | 15 + apps/spec/roll.md | 22 +- docker-compose.yml | 8 +- e2e/.eslintrc | 8 - e2e/tests/000-upload-showfile.spec.ts | 4 +- e2e/tests/002-view-navigation.spec.ts | 2 +- e2e/tests/features/204-editor-crud.spec.ts | 2 +- e2e/tests/features/205-operator.spec.ts | 2 +- e2e/tests/features/207-view-params.spec.ts | 2 +- e2e/tests/features/208-auxtimer.spec.ts | 2 +- .../features/209-rundown-shortcuts.spec.ts | 2 +- .../213-arrange-while-playing.spec.ts | 2 +- e2e/tests/fixtures/override.ts | 2 +- package.json | 16 +- packages/types/.eslintignore | 2 - packages/types/.eslintrc | 16 - packages/types/.oxlintrc.json | 5 + packages/types/package.json | 5 +- .../BackendResponse.type.ts | 2 +- .../src/definitions/core/Automation.type.ts | 2 +- packages/types/src/utils/guards.ts | 2 +- packages/types/tsconfig.json | 3 +- packages/utils/.eslintignore | 2 - packages/utils/.eslintrc | 16 - packages/utils/.oxlintrc.json | 5 + packages/utils/.prettierrc | 9 - packages/utils/package.json | 9 +- .../src/date-utils/checkIsNextDay.test.ts | 32 +- .../src/date-utils/getExpectedStart.test.ts | 44 +- .../utils/src/date-utils/getTimeFrom.test.ts | 32 +- .../utils/src/date-utils/isNewLatest.test.ts | 28 +- .../utils/src/date-utils/isTimeString.test.ts | 4 +- .../src/date-utils/parseUserTime.test.ts | 8 +- .../src/date-utils/timeFormatting.test.ts | 2 +- .../utils/src/regex-utils/isColourHex.test.ts | 12 +- .../src/rundown-utils/entryDefinitions.ts | 2 +- .../src/rundown-utils/rundownUtils.mock.ts | 2 +- .../src/validate-events/validateEvent.test.ts | 4 +- .../src/validate-events/validateEvent.ts | 2 +- .../utils/tsconfig.app.json | 19 +- packages/utils/tsconfig.json | 26 +- packages/utils/tsconfig.tests.json | 20 - packages/utils/tsconfig.vitest.json | 13 + pnpm-lock.yaml | 3059 +++++------------ pnpm-workspace.yaml | 10 +- tsconfig.tests.json | 17 - 501 files changed, 2678 insertions(+), 4654 deletions(-) delete mode 100644 .eslintignore delete mode 100644 .eslintrc create mode 100644 .oxfmtrc.json create mode 100644 .oxlintrc.json delete mode 100644 .prettierignore delete mode 100644 .prettierrc delete mode 100644 apps/cli/.eslintrc create mode 100644 apps/cli/.oxlintrc.json delete mode 100644 apps/cli/.prettierrc delete mode 100644 apps/client/.eslintignore delete mode 100644 apps/client/.eslintrc create mode 100644 apps/client/.oxlintrc.json delete mode 100644 apps/client/.prettierrc rename apps/client/{tsconfig.tests.json => tsconfig.app.json} (65%) create mode 100644 apps/client/tsconfig.vitest.json delete mode 100644 apps/electron/.eslintignore delete mode 100644 apps/electron/.eslintrc create mode 100644 apps/electron/.oxlintrc.json delete mode 100644 apps/resolver/.eslintignore create mode 100644 apps/resolver/.oxlintrc.json create mode 100644 apps/resolver/tsconfig.dts.json delete mode 100644 apps/server/.eslintignore delete mode 100644 apps/server/.eslintrc create mode 100644 apps/server/.oxlintrc.json delete mode 100644 apps/server/.prettierrc create mode 100644 apps/server/tsconfig.app.json delete mode 100644 apps/server/tsconfig.tests.json create mode 100644 apps/server/tsconfig.vitest.json delete mode 100644 e2e/.eslintrc delete mode 100644 packages/types/.eslintignore delete mode 100644 packages/types/.eslintrc create mode 100644 packages/types/.oxlintrc.json delete mode 100644 packages/utils/.eslintignore delete mode 100644 packages/utils/.eslintrc create mode 100644 packages/utils/.oxlintrc.json delete mode 100644 packages/utils/.prettierrc rename apps/resolver/tsconfig.tests.json => packages/utils/tsconfig.app.json (51%) delete mode 100644 packages/utils/tsconfig.tests.json create mode 100644 packages/utils/tsconfig.vitest.json delete mode 100644 tsconfig.tests.json diff --git a/.dockerignore b/.dockerignore index c9eb575a4..9de9e8896 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,5 +1,5 @@ -# Ignore config files -.prettier* +# Ignore formatter config files +.oxfmt* # Ignore install stuff **/yarn.lock diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 877ad032b..000000000 --- a/.eslintignore +++ /dev/null @@ -1,2 +0,0 @@ - "ONTIME_VERSION.js" -dist/ diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index ba69357eb..000000000 --- a/.eslintrc +++ /dev/null @@ -1,53 +0,0 @@ -{ - "root": true, - "parserOptions": { - "ecmaVersion": 2020 - }, - "env": { - "es6": true, - "jest": true - }, - "parser": "@typescript-eslint/parser", - "extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended", "prettier"], - "plugins": ["@typescript-eslint", "prettier"], - "overrides": [ - { - "files": ["e2e/**/**.spec.ts", "e2e/**/**.test.ts"], - "extends": ["plugin:playwright/playwright-test"] - } - ], - "rules": { - "no-useless-concat": "warn", - "prefer-template": "warn", - "no-throw-literal": "error", - "no-console": [ - "warn", - { - "allow": ["warn", "error"] - } - ], - "no-restricted-imports": [ - "error", - { - "patterns": ["ontime-types/src/*", "ontime-utils/src/*"] - } - ], - "@typescript-eslint/no-non-null-assertion": "warn", - "@typescript-eslint/no-explicit-any": "warn", - "@typescript-eslint/no-unused-vars": [ - "error", - { - "argsIgnorePattern": "^_", - "caughtErrorsIgnorePattern": "^_", - "destructuredArrayIgnorePattern": "^_", - "varsIgnorePattern": "^_" - } - ], - "prettier/prettier": [ - "warn", - { - "endOfLine": "auto" - } - ] - } -} diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 50e60c742..c82616a4c 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,2 +1,2 @@ github: cpvalente -buy_me_a_coffee: cpvalente \ No newline at end of file +buy_me_a_coffee: cpvalente diff --git a/.github/workflows/build_docker.yml b/.github/workflows/build_docker.yml index 176152b27..cac264965 100644 --- a/.github/workflows/build_docker.yml +++ b/.github/workflows/build_docker.yml @@ -64,4 +64,4 @@ jobs: # Push is a shorthand for --output=type=registry push: true tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} \ No newline at end of file + labels: ${{ steps.meta.outputs.labels }} diff --git a/.gitignore b/.gitignore index 2b9718157..deb50432a 100644 --- a/.gitignore +++ b/.gitignore @@ -33,6 +33,7 @@ e2e/tests/fixtures/tmp/* # production build/ dist/ +*.tsbuildinfo # bundled assets translations.json @@ -51,4 +52,4 @@ ontime-data/ **/ONTIME_VERSION.js # temporary write files -**.tmp \ No newline at end of file +**.tmp diff --git a/.oxfmtrc.json b/.oxfmtrc.json new file mode 100644 index 000000000..8645bee62 --- /dev/null +++ b/.oxfmtrc.json @@ -0,0 +1,25 @@ +{ + "$schema": "./node_modules/oxfmt/configuration_schema.json", + "endOfLine": "lf", + "trailingComma": "all", + "tabWidth": 2, + "semi": true, + "singleQuote": true, + "jsxSingleQuote": true, + "printWidth": 120, + "sortPackageJson": false, + "sortImports": {}, + "ignorePatterns": [ + "build", + "coverage", + "dist", + "node_modules", + "playwright-report", + "pnpm-lock.yaml", + "**/*.toml", + "**/*.json", + "!tsconfig.common.json", + "!turbo.json", + "!package.json" + ] +} diff --git a/.oxlintrc.json b/.oxlintrc.json new file mode 100644 index 000000000..bc3f4c27f --- /dev/null +++ b/.oxlintrc.json @@ -0,0 +1,37 @@ +{ + "$schema": "./node_modules/oxlint/configuration_schema.json", + "categories": { + "correctness": "warn", + "suspicious": "off", + "pedantic": "off", + "perf": "warn", + "style": "off", + "restriction": "off", + "nursery": "off" + }, + "rules": { + "no-unused-vars": [ + "error", + { + "argsIgnorePattern": "^_", + "varsIgnorePattern": "^_", + "caughtErrorsIgnorePattern": "^_", + "destructuredArrayIgnorePattern": "^_", + "caughtErrors": "none" + } + ], + "no-restricted-imports": [ + "error", + { + "patterns": ["ontime-types/src/*", "ontime-utils/src/*"] + } + ] + }, + "ignorePatterns": [ + "**/node_modules/**", + "**/dist/**", + "apps/client/build/**", + "apps/electron/assets/**", + "**/ONTIME_VERSION.js" + ] +} diff --git a/.prettierignore b/.prettierignore deleted file mode 100644 index 2f6778d66..000000000 --- a/.prettierignore +++ /dev/null @@ -1,14 +0,0 @@ -build -coverage -dist -node_modules - -playwright-report - - -pnpm-lock.yaml -**/*.toml -**/*.json -!tsconfig.common.json -!turbo.json -!package.json diff --git a/.prettierrc b/.prettierrc deleted file mode 100644 index 66c9b5f83..000000000 --- a/.prettierrc +++ /dev/null @@ -1,9 +0,0 @@ -{ - "endOfLine": "lf", - "trailingComma": "all", - "tabWidth": 2, - "semi": true, - "singleQuote": true, - "jsxSingleQuote": true, - "printWidth": 120 -} diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index cca430a29..b52d20dfb 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -2,16 +2,16 @@ Ontime consists of 3 distinct parts -- __client__: A React app for Ontime's UI and web clients -- __electron__: An electron app which facilitates the cross-platform distribution of Ontime -- __server__: A node application which handles the domains services and integrations +- **client**: A React app for Ontime's UI and web clients +- **electron**: An electron app which facilitates the cross-platform distribution of Ontime +- **server**: A node application which handles the domains services and integrations The steps below will assume you have locally installed the necessary dependencies. Other dependencies will be installed as part of the setup -- __node__ (~22) -- __pnpm__ (~10) -- __docker__ (only necessary to run and build docker images) +- **node** (~22) +- **pnpm** (~10) +- **docker** (only necessary to run and build docker images) ## LOCAL DEVELOPMENT @@ -20,10 +20,10 @@ development. Locally, we would need to run both the React client and the node.js server in development mode From the project root, run the following commands -- __Install the project dependencies__ by running `pnpm i` -- __Create a local build__ by running `pnpm build`, this will populate local dependencies -- __Run dev mode__ by running `pnpm dev` or `pnpm dev:electron` to get the electron window +- **Install the project dependencies** by running `pnpm i` +- **Create a local build** by running `pnpm build`, this will populate local dependencies +- **Run dev mode** by running `pnpm dev` or `pnpm dev:electron` to get the electron window ### Debugging backend @@ -31,8 +31,9 @@ The previous command will start the development servers for both the client, ser Typically in dev mode we prefer to start these in separate terminals to help with error tracking and debugging. We do that by creating two terminals an running -- __Run the React UI__ by running `pnpm dev --filter=ontime-ui` -- __Run the nodejs server__ by running `pnpm dev --filter=ontime-server` + +- **Run the React UI** by running `pnpm dev --filter=ontime-ui` +- **Run the nodejs server** by running `pnpm dev --filter=ontime-server` - If you need to set breakpoints and inspect the code execution, enable Node.js inspect mode by running `pnpm dev:inspect --filter=ontime-server`. @@ -77,9 +78,9 @@ You can generate a distribution for your OS by running the following steps. From the project root, run the following commands -- __Install the project dependencies__ by running `pnpm i` -- __Build the UI and server__ by running `pnpm build` -- __Create the package__ by running `pnpm dist-win`, `pnpm dist-mac` or `pnpm dist-linux` +- **Install the project dependencies** by running `pnpm i` +- **Build the UI and server** by running `pnpm build` +- **Create the package** by running `pnpm dist-win`, `pnpm dist-mac` or `pnpm dist-linux` The build distribution assets will be at `.apps/electron/dist` @@ -90,23 +91,24 @@ While it should allow for a generic setup, it might need to be modified to fit y From the project root, run the following commands -- __Build docker image from__ by running `docker build -t getontime/ontime .` -- __Run docker image from compose__ by running `docker-compose up -d` +- **Build docker image from** by running `docker build -t getontime/ontime .` +- **Run docker image from compose** by running `docker-compose up -d` Other useful commands -- __List running processes__ by running `docker ps` -- __Kill running process__ by running `docker kill ` +- **List running processes** by running `docker ps` +- **Kill running process** by running `docker kill ` ## CONTRIBUTION GUIDELINES If you want to propose changes to the codebase, please reach out before opening a Pull Request. For new PRs, please follow the following checklist: -* [ ] You have updated and ran unit locally and they are passing. Unit tests are generally created for all utility functions and business logic -* [ ] You have ran code formatting and linting in all your changes -* [ ] The branch is clean and the commits are meaningfully separated and contain descriptive messages -* [ ] The PR body contains description and motivation for the changes + +- [ ] You have updated and ran unit locally and they are passing. Unit tests are generally created for all utility functions and business logic +- [ ] You have ran code formatting and linting in all your changes +- [ ] The branch is clean and the commits are meaningfully separated and contain descriptive messages +- [ ] The PR body contains description and motivation for the changes After this checklist is complete, you can request a review from one of the maintainers to get feedback and approval on the changes. \ We will review as soon as possible diff --git a/README.md b/README.md index 6ca2e0b3c..aca2fee42 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ [![](https://img.shields.io/static/v1?label=Buy%20me%20a%20coffee&message=%E2%9D%A4&logo=buymeacoffee&color=%23fe8e86)](https://www.buymeacoffee.com/cpvalente) ## Download the latest release + Buy Me A Coffee - Download for Windows @@ -17,14 +18,17 @@ - Download AppImage for Linux (ARM 32-bit, older Raspberry Pi) ... or + - Get from Docker hub - Install from NPM - Install from Homebrew ## Need help? + We do our best to have most topics covered by the documentation. However, if your question is not covered, you are welcome to [fill in a bug report in an issue](https://github.com/cpvalente/ontime/issues), [ask a question in GitHub discussions](https://github.com/cpvalente/ontime/discussions) or hop in the [discord server](https://discord.com/invite/eje3CSUEXm) for a chat. ## Using Ontime? + Let us know! Ontime improves from the collaboration with its users. We would like to understand how you use Ontime and appreciate your feedback. @@ -43,6 +47,7 @@ Ontime is made by entertainment and broadcast engineers and used by - Houses of worship ## Main features + - **Multiplatform**: Available as a Cloud service and for Windows, macOS, Linux, or self-hosted via Docker. - **In any device**: Ontime is available to any device with a browser, eg: tablets, mobile phones, laptops, signage, media servers... - **Team Collaboration**: Dedicated views for directors, operators, backstage, and signage. @@ -111,7 +116,8 @@ If you are a developer and would like to contribute with code, please open an is Information about the project setup can be found in the [development documentation](./DEVELOPMENT.md) ## Links -- [Ontime website](https://getontime.no) + +- [Ontime website](https://getontime.no) - [Documentation](https://docs.getontime.no) - [Video tutorials](https://www.youtube.com/@ontimeapp) - [Ontime discord server](https://discord.com/invite/eje3CSUEXm) diff --git a/SPONSOR.md b/SPONSOR.md index f8a262ea4..e88790a0a 100644 --- a/SPONSOR.md +++ b/SPONSOR.md @@ -1,19 +1,24 @@ # Terms of sponsorship + Ontime does not exist as a fiscal entity. The sponsorship recipient is the project owner. In this light, contributors are funding the project owner's capacity to work on the project, not the project itself. As a contribution recipient, the code owner reserves the right to redistribute. ## Why sponsor + Ontime is and will remain free, regardless of your decision to contribute. Regardless, you may choose to provide a monetary contribution: ### Improve user experience + Certain parts of the application user experience are tied to our capacity to pay for services. App signing and Google Sheets integration are good examples of this. ### Cool stuff + We may choose not to implement some features. This could be related to the complexity required, to the skill set, or to the fact that we just feel it doesn't improve the app for a significant percentage of users. In those cases, a feature may be considered "not worth it," regardless of its pertinence. As a user, you can choose to sponsor a particular feature or donate to the app so that we can create bounties for features. ### Priorities + Monetary contributions are most immediately needed to offset the costs of presenting and distributing Ontime, i.e., hosting, domains, and certificates. Additional funding will be considered according to the needs at the time. diff --git a/apps/cli/.eslintrc b/apps/cli/.eslintrc deleted file mode 100644 index 192099671..000000000 --- a/apps/cli/.eslintrc +++ /dev/null @@ -1,16 +0,0 @@ -{ - "parserOptions": { - "sourceType": "module" - }, - "env": { - "browser": true, - "node": true - }, - "extends": [ - "eslint:recommended" - ], - "plugins": [], - "rules": { - "@typescript-eslint/no-var-requires": "off" - } -} diff --git a/apps/cli/.oxlintrc.json b/apps/cli/.oxlintrc.json new file mode 100644 index 000000000..f43f3d72f --- /dev/null +++ b/apps/cli/.oxlintrc.json @@ -0,0 +1,5 @@ +{ + "$schema": "../../node_modules/oxlint/configuration_schema.json", + "extends": ["../../.oxlintrc.json"], + "plugins": ["unicorn", "typescript", "oxc", "vitest"] +} diff --git a/apps/cli/.prettierrc b/apps/cli/.prettierrc deleted file mode 100644 index 66c9b5f83..000000000 --- a/apps/cli/.prettierrc +++ /dev/null @@ -1,9 +0,0 @@ -{ - "endOfLine": "lf", - "trailingComma": "all", - "tabWidth": 2, - "semi": true, - "singleQuote": true, - "jsxSingleQuote": true, - "printWidth": 120 -} diff --git a/apps/cli/README.md b/apps/cli/README.md index 753b1385d..69610fc1f 100644 --- a/apps/cli/README.md +++ b/apps/cli/README.md @@ -1,6 +1,7 @@ # Ontime CLI ![Ontime](https://github.com/cpvalente/ontime/blob/9e63261b350e5b7b61c7ffb17c9e75a6c5a8c711/.github/aux-images/editor.png) + > Ontime is an application for managing rundown and event timers. Congratulations! You got this far into Ontime's rabbit hole and want to manage your installation. @@ -10,33 +11,40 @@ The CLI tool is a fast and lightweight way of installing Ontime and is perfect f ## Getting started ### Prerequisites + You will need to have installed the correct version of node.js Please check [the app engines declaration](https://github.com/cpvalente/ontime/blob/master/package.json) for the correct version. ### Running Ontime + To get Ontime running, all you need to do is install it in your system using your package manager of choice: -Install globally in your system +Install globally in your system + ```bash npm install -g @getontime/cli ``` ... and run using the installed script + ```bash ontime ``` Or install and run ontime (the installation here is temporary for the duration of the session) + ```bash npx install @getontime/cli ``` ## Links + - [Ontime's repository](https://github.com/cpvalente/ontime) - [Ontime's documentation](https://docs.getontime.no/) - [Ontime's website](https://getontime.no/) ## Sponsoring + You can help the development of this project or say thank you with a one time donation. \ See the [terms of donations](https://github.com/cpvalente/ontime/blob/master/SPONSOR.md) diff --git a/apps/cli/package.json b/apps/cli/package.json index 5406a1af2..780ea529c 100644 --- a/apps/cli/package.json +++ b/apps/cli/package.json @@ -1,27 +1,22 @@ { - "name": "@getontime/cli", - "version": "4.5.0", - "author": "Carlos Valente", - "description": "Time keeping for live events", - "repository": "https://github.com/cpvalente/ontime", - "keywords": [ - "lighdev", - "ontime", - "timer" - ], - "license": "AGPL-3.0-only", - "main": "main.js", - "bin": { - "ontime": "main.js" - }, - "files": [ - "client", - "external", - "server" - ], - "devDependencies": { - "eslint": "catalog:", - "eslint-config-prettier": "catalog:", - "prettier": "catalog:" - } -} \ No newline at end of file + "name": "@getontime/cli", + "version": "4.5.0", + "author": "Carlos Valente", + "description": "Time keeping for live events", + "repository": "https://github.com/cpvalente/ontime", + "keywords": [ + "lighdev", + "ontime", + "timer" + ], + "license": "AGPL-3.0-only", + "main": "main.js", + "bin": { + "ontime": "main.js" + }, + "files": [ + "client", + "external", + "server" + ] +} diff --git a/apps/client/.eslintignore b/apps/client/.eslintignore deleted file mode 100644 index b7dab5e9c..000000000 --- a/apps/client/.eslintignore +++ /dev/null @@ -1,2 +0,0 @@ -node_modules -build \ No newline at end of file diff --git a/apps/client/.eslintrc b/apps/client/.eslintrc deleted file mode 100644 index c1ac8d56d..000000000 --- a/apps/client/.eslintrc +++ /dev/null @@ -1,142 +0,0 @@ -{ - "settings": { - "react": { - "version": "detect" - } - }, - "env": { - "browser": true, - "node": true - }, - "extends": [ - "plugin:react/recommended", - "plugin:react-hooks/recommended", - "plugin:@tanstack/eslint-plugin-query/recommended" - ], - "plugins": [ - "react", - "react-compiler", - "simple-import-sort", - "@tanstack/query" - ], - "rules": { - "react-compiler/react-compiler": "warn", - "react/jsx-no-bind": [ - "error", - { - "ignoreRefs": true, - "allowArrowFunctions": true, - "allowFunctions": false, - "allowBind": false, - "ignoreDOMComponents": true - } - ], - "react/jsx-boolean-value": [ - "error", - "never", - { - "always": [] - } - ], - "react/jsx-handler-names": [ - "off", - { - "eventHandlerPrefix": "handle", - "eventHandlerPropPrefix": "on" - } - ], - "react/no-danger": "warn", - "react/no-deprecated": [ - "error" - ], - "react/jsx-uses-react": "off", - "react/react-in-jsx-scope": "off", - "react/jsx-no-undef": "error", - "react/jsx-closing-tag-location": "warn", - "react/jsx-no-useless-fragment": "warn", - "react/no-unescaped-entities": "error", - "react/jsx-tag-spacing": [ - "error", - { - "closingSlash": "never", - "beforeSelfClosing": "always", - "afterOpening": "never", - "beforeClosing": "never" - } - ], - "react/jsx-space-before-closing": [ - "off", - "always" - ], - "react/jsx-curly-brace-presence": [ - "error", - { - "props": "never", - "children": "never" - } - ], - "react/destructuring-assignment": [ - "error", - "always" - ], - "react/no-unsafe": "off", - "react/prop-types": [ - "error", - { - "ignore": [], - "customValidators": [], - "skipUndeclared": true - } - ], - "simple-import-sort/imports": "warn", - "simple-import-sort/exports": "warn" - }, - "overrides": [ - // override "simple-import-sort" config - { - "files": [ - "*.js", - "*.jsx", - "*.ts", - "*.tsx" - ], - "rules": { - "simple-import-sort/imports": [ - "error", - { - "groups": [ - // Packages `react` related packages come first. - [ - "^react", - "^@?\\w" - ], - // Internal packages. - [ - "^(@|components)(/.*|$)" - ], - // Side effect imports. - [ - "^\\u0000" - ], - // Parent imports. Put `..` last. - [ - "^\\.\\.(?!/?$)", - "^\\.\\./?$" - ], - // Other relative imports. Put same-folder imports and `.` last. - [ - "^\\./(?=.*/)(?!/?$)", - "^\\.(?!/?$)", - "^\\./?$" - ], - // Style imports. - [ - "^.+\\.?(css)$" - ] - ] - } - ] - } - } - ] -} diff --git a/apps/client/.oxlintrc.json b/apps/client/.oxlintrc.json new file mode 100644 index 000000000..b96efc20d --- /dev/null +++ b/apps/client/.oxlintrc.json @@ -0,0 +1,5 @@ +{ + "$schema": "../../node_modules/oxlint/configuration_schema.json", + "extends": ["../../.oxlintrc.json"], + "plugins": ["unicorn", "typescript", "oxc", "react", "vitest"] +} diff --git a/apps/client/.prettierrc b/apps/client/.prettierrc deleted file mode 100644 index 66c9b5f83..000000000 --- a/apps/client/.prettierrc +++ /dev/null @@ -1,9 +0,0 @@ -{ - "endOfLine": "lf", - "trailingComma": "all", - "tabWidth": 2, - "semi": true, - "singleQuote": true, - "jsxSingleQuote": true, - "printWidth": 120 -} diff --git a/apps/client/package.json b/apps/client/package.json index 62935224d..191da1aa8 100644 --- a/apps/client/package.json +++ b/apps/client/package.json @@ -37,8 +37,8 @@ "postinstall": "pnpm addversion", "dev": "cross-env BROWSER=none vite", "dev:electron": "pnpm dev", - "lint": "eslint . --quiet", - "typecheck": "tsc --noEmit", + "lint": "oxlint --quiet --type-aware", + "typecheck": "tsc -p tsconfig.app.json --noEmit", "build": "vite build", "test": "vitest", "test:pipeline": "vitest run", @@ -58,25 +58,13 @@ }, "devDependencies": { "@sentry/vite-plugin": "^2.16.1", - "@tanstack/eslint-plugin-query": "^5.8.4", "@types/prismjs": "^1.26.5", "@types/react": "^19.1.12", "@types/react-dom": "^19.1.9", - "@typescript-eslint/eslint-plugin": "catalog:", - "@typescript-eslint/parser": "catalog:", "@vitejs/plugin-react": "4.5.1", "babel-plugin-react-compiler": "1.0.0", - "eslint": "catalog:", - "eslint-config-prettier": "catalog:", - "eslint-plugin-jest": "^28.6.0", - "eslint-plugin-prettier": "catalog:", - "eslint-plugin-react": "^7.32.0", - "eslint-plugin-react-compiler": "19.1.0-rc.2", - "eslint-plugin-react-hooks": "^5.2.0", - "eslint-plugin-simple-import-sort": "^8.0.0", "ontime-types": "workspace:*", "ontime-utils": "workspace:*", - "prettier": "catalog:", "sass": "^1.57.1", "typescript": "catalog:", "vite": "6.3.1", diff --git a/apps/client/public/site.webmanifest b/apps/client/public/site.webmanifest index fa64d6794..5e9522c3d 100644 --- a/apps/client/public/site.webmanifest +++ b/apps/client/public/site.webmanifest @@ -1,9 +1,7 @@ { "name": "", "short_name": "", - "icons": [ - { "src": "/ontime-logo.png", "sizes": "295x295", "type": "image/png" } - ], + "icons": [{ "src": "/ontime-logo.png", "sizes": "295x295", "type": "image/png" }], "theme_color": "#2B5ABC", "background_color": "#101010", "display": "standalone" diff --git a/apps/client/src/App.tsx b/apps/client/src/App.tsx index a01e4bce8..b723476bf 100644 --- a/apps/client/src/App.tsx +++ b/apps/client/src/App.tsx @@ -1,20 +1,19 @@ -import { BrowserRouter } from 'react-router'; import { Tooltip } from '@base-ui/react/tooltip'; import { QueryClientProvider } from '@tanstack/react-query'; import { ReactQueryDevtools } from '@tanstack/react-query-devtools'; +import { BrowserRouter } from 'react-router'; // apply global axios config defaults import './common/api/axios.config'; - +import AppRouter from './AppRouter'; import ErrorBoundary from './common/components/error-boundary/ErrorBoundary'; import IdentifyOverlay from './common/components/identify-overlay/IdentifyOverlay'; import { AppContextProvider } from './common/context/AppContext'; import { ontimeQueryClient } from './common/queryClient'; import { connectSocket } from './common/utils/socket'; +import { baseURI } from './externals'; import KeepAwake from './features/keep-awake/KeepAwake'; import { TranslationProvider } from './translation/TranslationProvider'; -import AppRouter from './AppRouter'; -import { baseURI } from './externals'; connectSocket(); diff --git a/apps/client/src/AppRouter.tsx b/apps/client/src/AppRouter.tsx index 8dbe62385..34d21b950 100644 --- a/apps/client/src/AppRouter.tsx +++ b/apps/client/src/AppRouter.tsx @@ -1,18 +1,18 @@ -import { ComponentType, lazy, Suspense, useEffect, useMemo } from 'react'; -import { Navigate, Route, useLocation, useNavigate, useParams } from 'react-router'; import { OntimeView, OntimeViewPresettable, URLPreset } from 'ontime-types'; +import { ComponentType, Suspense, lazy, useEffect, useMemo } from 'react'; +import { Navigate, Route, useLocation, useNavigate, useParams } from 'react-router'; import ViewNavigationMenu from './common/components/navigation-menu/ViewNavigationMenu'; import { PresetContext } from './common/context/PresetContext'; -import { useClientPath } from './common/hooks/useClientPath'; import useUrlPresets from './common/hooks-query/useUrlPresets'; +import { useClientPath } from './common/hooks/useClientPath'; import { getRouteFromPreset } from './common/utils/urlPresets'; +import { getIsNavigationLocked, sessionScope } from './externals'; import Log from './features/log/Log'; +import { initializeSentry } from './sentry.config'; import Loader from './views/common/loader/Loader'; import NotFound from './views/common/not-found/NotFound'; import ViewLoader from './views/ViewLoader'; -import { getIsNavigationLocked, sessionScope } from './externals'; -import { initializeSentry } from './sentry.config'; const Timer = lazy(() => import('./views/timer/Timer')); const Countdown = lazy(() => import('./views/countdown/Countdown')); diff --git a/apps/client/src/common/api/assets.ts b/apps/client/src/common/api/assets.ts index f853eb5b8..24efe1962 100644 --- a/apps/client/src/common/api/assets.ts +++ b/apps/client/src/common/api/assets.ts @@ -2,8 +2,7 @@ import axios from 'axios'; import { TranslationObject } from 'ontime-types'; import { ontimeQueryClient } from '../../common/queryClient'; - -import { apiEntryUrl, customTranslationsURL, TRANSLATION } from './constants'; +import { TRANSLATION, apiEntryUrl, customTranslationsURL } from './constants'; import type { RequestOptions } from './requestOptions'; const assetsPath = `${apiEntryUrl}/assets`; diff --git a/apps/client/src/common/api/external.ts b/apps/client/src/common/api/external.ts index 7156b4609..59294a3de 100644 --- a/apps/client/src/common/api/external.ts +++ b/apps/client/src/common/api/external.ts @@ -1,7 +1,6 @@ import axios from 'axios'; import { apiRepoLatest } from '../../externals'; - import type { RequestOptions } from './requestOptions'; export type HasUpdate = { diff --git a/apps/client/src/common/api/report.ts b/apps/client/src/common/api/report.ts index 42a5c687f..778545257 100644 --- a/apps/client/src/common/api/report.ts +++ b/apps/client/src/common/api/report.ts @@ -2,8 +2,7 @@ import axios from 'axios'; import { OntimeReport } from 'ontime-types'; import { ontimeQueryClient } from '../../common/queryClient'; - -import { apiEntryUrl, REPORT } from './constants'; +import { REPORT, apiEntryUrl } from './constants'; import type { RequestOptions } from './requestOptions'; export const reportUrl = `${apiEntryUrl}/report`; diff --git a/apps/client/src/common/api/sheets.ts b/apps/client/src/common/api/sheets.ts index 27fefa329..9884e0b3e 100644 --- a/apps/client/src/common/api/sheets.ts +++ b/apps/client/src/common/api/sheets.ts @@ -76,14 +76,10 @@ export const previewRundown = async ( }; export const getWorksheetNames = async (sheetId: string, requestOptions?: RequestOptions): Promise => { - const response: AxiosResponse = await axios.post( - `${sheetsPath}/${sheetId}/worksheets`, - undefined, - { - signal: requestOptions?.signal, - timeout: requestOptions?.timeout ?? axiosConfig.longTimeout, - }, - ); + const response: AxiosResponse = await axios.post(`${sheetsPath}/${sheetId}/worksheets`, undefined, { + signal: requestOptions?.signal, + timeout: requestOptions?.timeout ?? axiosConfig.longTimeout, + }); return response.data; }; diff --git a/apps/client/src/common/components/checkbox/Checkbox.tsx b/apps/client/src/common/components/checkbox/Checkbox.tsx index 0cd1d42fd..547cbc643 100644 --- a/apps/client/src/common/components/checkbox/Checkbox.tsx +++ b/apps/client/src/common/components/checkbox/Checkbox.tsx @@ -1,5 +1,5 @@ -import { IoCheckmark } from 'react-icons/io5'; import { Checkbox as BaseCheckbox } from '@base-ui/react/checkbox'; +import { IoCheckmark } from 'react-icons/io5'; import style from './Checkbox.module.scss'; diff --git a/apps/client/src/common/components/client-modal/RedirectClientModal.tsx b/apps/client/src/common/components/client-modal/RedirectClientModal.tsx index 992c6cadb..f577316ee 100644 --- a/apps/client/src/common/components/client-modal/RedirectClientModal.tsx +++ b/apps/client/src/common/components/client-modal/RedirectClientModal.tsx @@ -2,8 +2,8 @@ import { useState } from 'react'; import { IoArrowForward } from 'react-icons/io5'; import { navigatorConstants } from '../../../viewerConfig'; -import { setClientRemote } from '../../hooks/useSocket'; import useUrlPresets from '../../hooks-query/useUrlPresets'; +import { setClientRemote } from '../../hooks/useSocket'; import Button from '../buttons/Button'; import Dialog from '../dialog/Dialog'; import Info from '../info/Info'; diff --git a/apps/client/src/common/components/dialog/Dialog.tsx b/apps/client/src/common/components/dialog/Dialog.tsx index f89fec096..114cbd636 100644 --- a/apps/client/src/common/components/dialog/Dialog.tsx +++ b/apps/client/src/common/components/dialog/Dialog.tsx @@ -1,6 +1,6 @@ +import { Dialog as BaseDialog } from '@base-ui/react/dialog'; import type { ReactNode } from 'react'; import { IoClose } from 'react-icons/io5'; -import { Dialog as BaseDialog } from '@base-ui/react/dialog'; import IconButton from '../buttons/IconButton'; diff --git a/apps/client/src/common/components/dropdown-menu/DropdownMenu.tsx b/apps/client/src/common/components/dropdown-menu/DropdownMenu.tsx index 58b6577f7..9233b5690 100644 --- a/apps/client/src/common/components/dropdown-menu/DropdownMenu.tsx +++ b/apps/client/src/common/components/dropdown-menu/DropdownMenu.tsx @@ -1,6 +1,6 @@ +import { Menu as BaseMenu } from '@base-ui/react/menu'; import { PropsWithChildren } from 'react'; import { IconType } from 'react-icons'; -import { Menu as BaseMenu } from '@base-ui/react/menu'; import style from './DropdownMenu.module.scss'; diff --git a/apps/client/src/common/components/error-boundary/ErrorBoundary.jsx b/apps/client/src/common/components/error-boundary/ErrorBoundary.jsx index bacd43fff..bda907ddc 100644 --- a/apps/client/src/common/components/error-boundary/ErrorBoundary.jsx +++ b/apps/client/src/common/components/error-boundary/ErrorBoundary.jsx @@ -1,7 +1,7 @@ -/* eslint-disable react/destructuring-assignment */ -import React from 'react'; // skipcq: JS-C1003 - sentry does not expose itself as an ES Module. import * as Sentry from '@sentry/react'; +/* eslint-disable react/destructuring-assignment */ +import React from 'react'; import { hasConnected, reconnectAttempts } from '../../../common/utils/socket'; import { runtimeStore } from '../../stores/runtime'; diff --git a/apps/client/src/common/components/identify-overlay/IdentifyOverlay.tsx b/apps/client/src/common/components/identify-overlay/IdentifyOverlay.tsx index df68d347c..ce980d671 100644 --- a/apps/client/src/common/components/identify-overlay/IdentifyOverlay.tsx +++ b/apps/client/src/common/components/identify-overlay/IdentifyOverlay.tsx @@ -1,6 +1,6 @@ +import { MILLIS_PER_MINUTE } from 'ontime-utils'; import { useCallback, useEffect, useRef } from 'react'; import { createPortal } from 'react-dom'; -import { MILLIS_PER_MINUTE } from 'ontime-utils'; import { setClientRemote } from '../../hooks/useSocket'; import { useClientStore } from '../../stores/clientStore'; diff --git a/apps/client/src/common/components/input/auto-textarea/AutoTextarea.tsx b/apps/client/src/common/components/input/auto-textarea/AutoTextarea.tsx index ba91fd1a3..4c403401e 100644 --- a/apps/client/src/common/components/input/auto-textarea/AutoTextarea.tsx +++ b/apps/client/src/common/components/input/auto-textarea/AutoTextarea.tsx @@ -1,6 +1,6 @@ -import { RefObject, useEffect } from 'react'; // @ts-expect-error no types from library import autosize from 'autosize/dist/autosize'; +import { RefObject, useEffect } from 'react'; import Textarea, { type TextareaProps } from '../textarea/Textarea'; diff --git a/apps/client/src/common/components/input/colour-input/SwatchPicker.tsx b/apps/client/src/common/components/input/colour-input/SwatchPicker.tsx index 3686c9f6b..ee44576d4 100644 --- a/apps/client/src/common/components/input/colour-input/SwatchPicker.tsx +++ b/apps/client/src/common/components/input/colour-input/SwatchPicker.tsx @@ -1,7 +1,7 @@ -import { useController, UseControllerProps } from 'react-hook-form'; -import { IoEyedrop } from 'react-icons/io5'; import { useDebouncedCallback } from '@mantine/hooks'; import { ViewSettings } from 'ontime-types'; +import { UseControllerProps, useController } from 'react-hook-form'; +import { IoEyedrop } from 'react-icons/io5'; import { cx, getAccessibleColour } from '../../../utils/styleUtils'; import PopoverPicker from '../popover-picker/PopoverPicker'; diff --git a/apps/client/src/common/components/input/input/Input.tsx b/apps/client/src/common/components/input/input/Input.tsx index 00695bac3..00251a944 100644 --- a/apps/client/src/common/components/input/input/Input.tsx +++ b/apps/client/src/common/components/input/input/Input.tsx @@ -1,4 +1,4 @@ -import { forwardRef, InputHTMLAttributes } from 'react'; +import { InputHTMLAttributes, forwardRef } from 'react'; import { cx } from '../../../utils/styleUtils'; diff --git a/apps/client/src/common/components/input/popover-picker/PopoverPicker.tsx b/apps/client/src/common/components/input/popover-picker/PopoverPicker.tsx index 0d29b565d..fc1e81cc0 100644 --- a/apps/client/src/common/components/input/popover-picker/PopoverPicker.tsx +++ b/apps/client/src/common/components/input/popover-picker/PopoverPicker.tsx @@ -1,6 +1,6 @@ +import { Popover } from '@base-ui/react/popover'; import { PropsWithChildren } from 'react'; import { HexAlphaColorPicker, HexColorInput } from 'react-colorful'; -import { Popover } from '@base-ui/react/popover'; import PopoverContents from '../../popover/Popover'; diff --git a/apps/client/src/common/components/input/text-input/useReactiveTextInput.tsx b/apps/client/src/common/components/input/text-input/useReactiveTextInput.tsx index 3185e40d5..8558a2c29 100644 --- a/apps/client/src/common/components/input/text-input/useReactiveTextInput.tsx +++ b/apps/client/src/common/components/input/text-input/useReactiveTextInput.tsx @@ -1,5 +1,5 @@ +import { HotkeyItem, getHotkeyHandler } from '@mantine/hooks'; import { ChangeEvent, KeyboardEvent, RefObject, useCallback, useEffect, useMemo, useRef, useState } from 'react'; -import { getHotkeyHandler, HotkeyItem } from '@mantine/hooks'; interface UseReactiveTextInputReturn { value: string; diff --git a/apps/client/src/common/components/input/textarea/Textarea.tsx b/apps/client/src/common/components/input/textarea/Textarea.tsx index 5220d599d..64253e828 100644 --- a/apps/client/src/common/components/input/textarea/Textarea.tsx +++ b/apps/client/src/common/components/input/textarea/Textarea.tsx @@ -1,4 +1,4 @@ -import { forwardRef, TextareaHTMLAttributes } from 'react'; +import { TextareaHTMLAttributes, forwardRef } from 'react'; import { cx } from '../../../utils/styleUtils'; diff --git a/apps/client/src/common/components/input/time-input/NullableTimeInput.tsx b/apps/client/src/common/components/input/time-input/NullableTimeInput.tsx index 3b87384f9..099b06333 100644 --- a/apps/client/src/common/components/input/time-input/NullableTimeInput.tsx +++ b/apps/client/src/common/components/input/time-input/NullableTimeInput.tsx @@ -1,5 +1,5 @@ -import { FocusEvent, KeyboardEvent, useCallback, useEffect, useRef, useState } from 'react'; import { millisToString, parseUserTime } from 'ontime-utils'; +import { FocusEvent, KeyboardEvent, useCallback, useEffect, useRef, useState } from 'react'; import { cx } from '../../../utils/styleUtils'; import Input from '../input/Input'; diff --git a/apps/client/src/common/components/input/time-input/TimeInput.tsx b/apps/client/src/common/components/input/time-input/TimeInput.tsx index 902200a64..9ce94785d 100644 --- a/apps/client/src/common/components/input/time-input/TimeInput.tsx +++ b/apps/client/src/common/components/input/time-input/TimeInput.tsx @@ -1,5 +1,5 @@ -import { FocusEvent, KeyboardEvent, useCallback, useEffect, useRef, useState } from 'react'; import { millisToString, parseUserTime } from 'ontime-utils'; +import { FocusEvent, KeyboardEvent, useCallback, useEffect, useRef, useState } from 'react'; import { cx } from '../../../utils/styleUtils'; import Input from '../input/Input'; diff --git a/apps/client/src/common/components/link/external-link/ExternalLink.module.scss b/apps/client/src/common/components/link/external-link/ExternalLink.module.scss index 8b71d6b90..83c26d3e8 100644 --- a/apps/client/src/common/components/link/external-link/ExternalLink.module.scss +++ b/apps/client/src/common/components/link/external-link/ExternalLink.module.scss @@ -18,7 +18,7 @@ } &:focus { - outline: none; + outline: none; box-shadow: 0 1px 0 0 currentColor; } -} +} diff --git a/apps/client/src/common/components/modal/Modal.module.scss b/apps/client/src/common/components/modal/Modal.module.scss index d8adc4644..a8e72b1b3 100644 --- a/apps/client/src/common/components/modal/Modal.module.scss +++ b/apps/client/src/common/components/modal/Modal.module.scss @@ -3,7 +3,7 @@ top: 10vh; left: 50%; transform: translateX(-50%); - + padding-inline: 1rem; min-width: min(880px, 90vw); min-height: min(200px, 10vh); diff --git a/apps/client/src/common/components/modal/Modal.tsx b/apps/client/src/common/components/modal/Modal.tsx index b98a0c88a..57c3be500 100644 --- a/apps/client/src/common/components/modal/Modal.tsx +++ b/apps/client/src/common/components/modal/Modal.tsx @@ -1,6 +1,6 @@ +import { Dialog as BaseDialog } from '@base-ui/react/dialog'; import type { ReactNode } from 'react'; import { IoClose } from 'react-icons/io5'; -import { Dialog as BaseDialog } from '@base-ui/react/dialog'; import IconButton from '../buttons/IconButton'; diff --git a/apps/client/src/common/components/navigation-menu/NavigationMenu.tsx b/apps/client/src/common/components/navigation-menu/NavigationMenu.tsx index 9d22ccb47..765cfc2ef 100644 --- a/apps/client/src/common/components/navigation-menu/NavigationMenu.tsx +++ b/apps/client/src/common/components/navigation-menu/NavigationMenu.tsx @@ -1,9 +1,9 @@ +import { Dialog } from '@base-ui/react/dialog'; +import { useDisclosure, useFullscreen } from '@mantine/hooks'; import { memo } from 'react'; import { IoClose, IoContract, IoExpand, IoLockClosedOutline, IoSwapVertical } from 'react-icons/io5'; import { LuCoffee } from 'react-icons/lu'; import { useLocation } from 'react-router'; -import { Dialog } from '@base-ui/react/dialog'; -import { useDisclosure, useFullscreen } from '@mantine/hooks'; import { isLocalhost, supportsFullscreen } from '../../../externals'; import { canUseWakeLock, useKeepAwakeOptions } from '../../../features/keep-awake/useWakeLock'; @@ -13,7 +13,6 @@ import { useClientStore } from '../../stores/clientStore'; import { useViewOptionsStore } from '../../stores/viewOptions'; import IconButton from '../buttons/IconButton'; import { RenameClientModal } from '../client-modal/RenameClientModal'; - import ClientLink from './client-link/ClientLink'; import EditorNavigation from './editor-navigation/EditorNavigation'; import NavigationMenuItem from './navigation-menu-item/NavigationMenuItem'; diff --git a/apps/client/src/common/components/navigation-menu/ViewNavigationMenu.tsx b/apps/client/src/common/components/navigation-menu/ViewNavigationMenu.tsx index bd4271528..fc233b2b6 100644 --- a/apps/client/src/common/components/navigation-menu/ViewNavigationMenu.tsx +++ b/apps/client/src/common/components/navigation-menu/ViewNavigationMenu.tsx @@ -1,11 +1,10 @@ -import { memo } from 'react'; import { useDisclosure, useHotkeys } from '@mantine/hooks'; +import { memo } from 'react'; import { useViewParamsEditorStore } from '../view-params-editor/viewParamsEditor.store'; - import FloatingNavigation from './floating-navigation/FloatingNavigation'; -import ViewLockedIcon from './view-locked-icon/ViewLockedIcon'; import NavigationMenu from './NavigationMenu'; +import ViewLockedIcon from './view-locked-icon/ViewLockedIcon'; interface ViewNavigationMenuProps { /** prevent navigation */ diff --git a/apps/client/src/common/components/navigation-menu/navigation-menu-item/NavigationMenuItem.tsx b/apps/client/src/common/components/navigation-menu/navigation-menu-item/NavigationMenuItem.tsx index 086bd4f23..789b3b99c 100644 --- a/apps/client/src/common/components/navigation-menu/navigation-menu-item/NavigationMenuItem.tsx +++ b/apps/client/src/common/components/navigation-menu/navigation-menu-item/NavigationMenuItem.tsx @@ -24,7 +24,9 @@ export default function NavigationMenuItem({ role='button' onClick={onClick} onKeyDown={(event) => { - isKeyEnter(event) && onClick(); + if (isKeyEnter(event)) { + onClick(); + } }} > {children} diff --git a/apps/client/src/common/components/popover/Popover.module.scss b/apps/client/src/common/components/popover/Popover.module.scss index b01bc436e..b7d3b565d 100644 --- a/apps/client/src/common/components/popover/Popover.module.scss +++ b/apps/client/src/common/components/popover/Popover.module.scss @@ -5,7 +5,7 @@ color: $ui-white; background-color: $gray-1250; - border-radius: 3px; + border-radius: 3px; box-shadow: $box-shadow-l1; border: 1px solid $gray-1000; @@ -27,4 +27,3 @@ font-size: 1rem; margin-bottom: 0.5rem; } - diff --git a/apps/client/src/common/components/popover/Popover.tsx b/apps/client/src/common/components/popover/Popover.tsx index 28b1cf211..b8628406c 100644 --- a/apps/client/src/common/components/popover/Popover.tsx +++ b/apps/client/src/common/components/popover/Popover.tsx @@ -1,5 +1,5 @@ -import { PropsWithChildren } from 'react'; import { Popover } from '@base-ui/react/popover'; +import { PropsWithChildren } from 'react'; import style from './Popover.module.scss'; diff --git a/apps/client/src/common/components/protect-route/ProtectRoute.tsx b/apps/client/src/common/components/protect-route/ProtectRoute.tsx index 540c24626..593f8ad95 100644 --- a/apps/client/src/common/components/protect-route/ProtectRoute.tsx +++ b/apps/client/src/common/components/protect-route/ProtectRoute.tsx @@ -2,7 +2,6 @@ import { PropsWithChildren, useCallback, useContext } from 'react'; import { isLocalhost } from '../../../externals'; import { AppContext } from '../../context/AppContext'; - import PinPage from './PinPage'; interface ProtectRouteProps { diff --git a/apps/client/src/common/components/scroll-area/ScrollArea.module.scss b/apps/client/src/common/components/scroll-area/ScrollArea.module.scss index 4d101aaa2..b71d65324 100644 --- a/apps/client/src/common/components/scroll-area/ScrollArea.module.scss +++ b/apps/client/src/common/components/scroll-area/ScrollArea.module.scss @@ -16,7 +16,7 @@ $thumb-color-hover: $white-60; width: 100%; overscroll-behavior: contain; - &:focus-visible { + &:focus-visible { outline: 2px solid $blue-500; outline-offset: -2px; } diff --git a/apps/client/src/common/components/scroll-area/ScrollArea.tsx b/apps/client/src/common/components/scroll-area/ScrollArea.tsx index 77fc69130..411cca4d0 100644 --- a/apps/client/src/common/components/scroll-area/ScrollArea.tsx +++ b/apps/client/src/common/components/scroll-area/ScrollArea.tsx @@ -1,5 +1,5 @@ -import { CSSProperties, PropsWithChildren, Ref } from 'react'; import { ScrollArea } from '@base-ui/react/scroll-area'; +import { CSSProperties, PropsWithChildren, Ref } from 'react'; import { cx } from '../../utils/styleUtils'; diff --git a/apps/client/src/common/components/select/Select.tsx b/apps/client/src/common/components/select/Select.tsx index e7c4f2cb2..9c3e2f419 100644 --- a/apps/client/src/common/components/select/Select.tsx +++ b/apps/client/src/common/components/select/Select.tsx @@ -1,6 +1,6 @@ +import { Select as BaseSelect } from '@base-ui/react/select'; import { IoCheckmark } from 'react-icons/io5'; import { LuChevronsUpDown } from 'react-icons/lu'; -import { Select as BaseSelect } from '@base-ui/react/select'; import { cx } from '../../utils/styleUtils'; diff --git a/apps/client/src/common/components/state/Empty.module.scss b/apps/client/src/common/components/state/Empty.module.scss index f9c4ac1fc..ea224ae95 100644 --- a/apps/client/src/common/components/state/Empty.module.scss +++ b/apps/client/src/common/components/state/Empty.module.scss @@ -10,7 +10,7 @@ .text { display: block; - margin-inline: auto;; + margin-inline: auto; font-weight: 600; font-size: 2em; max-width: 600px; diff --git a/apps/client/src/common/components/switch/Switch.module.scss b/apps/client/src/common/components/switch/Switch.module.scss index 322d53f30..acf01f824 100644 --- a/apps/client/src/common/components/switch/Switch.module.scss +++ b/apps/client/src/common/components/switch/Switch.module.scss @@ -2,13 +2,13 @@ position: relative; display: flex; align-items: center; - + /* Reset and base styles */ appearance: none; border: 1px solid transparent; border-radius: 99px; background-color: $gray-1100; - + /* Transitions */ transition: background-color 125ms cubic-bezier(0.26, 0.75, 0.38, 0.45); diff --git a/apps/client/src/common/components/tooltip/Tooltip.module.scss b/apps/client/src/common/components/tooltip/Tooltip.module.scss index aaec6aae6..be8b0a9d7 100644 --- a/apps/client/src/common/components/tooltip/Tooltip.module.scss +++ b/apps/client/src/common/components/tooltip/Tooltip.module.scss @@ -1,7 +1,7 @@ .tooltip { font-size: calc(1rem - 3px); background-color: $ui-white; - color: $ui-black; + color: $ui-black; padding: 0.125rem 0.5rem; border-radius: 2px; line-height: 1.25em; diff --git a/apps/client/src/common/components/tooltip/Tooltip.tsx b/apps/client/src/common/components/tooltip/Tooltip.tsx index ce4bead04..dbd00821d 100644 --- a/apps/client/src/common/components/tooltip/Tooltip.tsx +++ b/apps/client/src/common/components/tooltip/Tooltip.tsx @@ -1,5 +1,5 @@ -import { PropsWithChildren } from 'react'; import { Tooltip as BaseTooltip } from '@base-ui/react/tooltip'; +import { PropsWithChildren } from 'react'; import style from './Tooltip.module.scss'; diff --git a/apps/client/src/common/components/view-params-editor/ParamInput.tsx b/apps/client/src/common/components/view-params-editor/ParamInput.tsx index fdf6c9e2c..f95692403 100644 --- a/apps/client/src/common/components/view-params-editor/ParamInput.tsx +++ b/apps/client/src/common/components/view-params-editor/ParamInput.tsx @@ -6,7 +6,6 @@ import Checkbox from '../checkbox/Checkbox'; import Input from '../input/input/Input'; import Select, { SelectOption } from '../select/Select'; import Switch from '../switch/Switch'; - import InlineColourPicker from './InlineColourPicker'; import { ParamField } from './viewParams.types'; @@ -44,7 +43,7 @@ export default function ParamInput({ paramField }: ParamInputProps) { return ( ); } diff --git a/apps/client/src/common/components/view-params-editor/ViewParamsEditor.tsx b/apps/client/src/common/components/view-params-editor/ViewParamsEditor.tsx index 9fa66a5dd..c3477410f 100644 --- a/apps/client/src/common/components/view-params-editor/ViewParamsEditor.tsx +++ b/apps/client/src/common/components/view-params-editor/ViewParamsEditor.tsx @@ -1,15 +1,14 @@ +import { Dialog } from '@base-ui/react/dialog'; +import { OntimeView } from 'ontime-types'; import { FormEvent, memo } from 'react'; import { IoClose } from 'react-icons/io5'; import { useSearchParams } from 'react-router'; -import { Dialog } from '@base-ui/react/dialog'; -import { OntimeView } from 'ontime-types'; -import { useIsSmallScreen } from '../../hooks/useIsSmallScreen'; import useViewSettings from '../../hooks-query/useViewSettings'; +import { useIsSmallScreen } from '../../hooks/useIsSmallScreen'; import Button from '../buttons/Button'; import IconButton from '../buttons/IconButton'; import Info from '../info/Info'; - import { ViewOption } from './viewParams.types'; import { getPreservedSearchParams, getURLSearchParamsFromObj } from './viewParams.utils'; import { useViewParamsEditorStore } from './viewParamsEditor.store'; diff --git a/apps/client/src/common/components/view-params-editor/ViewParamsPresets.tsx b/apps/client/src/common/components/view-params-editor/ViewParamsPresets.tsx index 415ebd703..80386b75c 100644 --- a/apps/client/src/common/components/view-params-editor/ViewParamsPresets.tsx +++ b/apps/client/src/common/components/view-params-editor/ViewParamsPresets.tsx @@ -1,5 +1,5 @@ -import { useSearchParams } from 'react-router'; import { OntimeView, URLPreset } from 'ontime-types'; +import { useSearchParams } from 'react-router'; import { useViewUrlPresets } from '../../hooks-query/useUrlPresets'; import { cx } from '../../utils/styleUtils'; diff --git a/apps/client/src/common/components/view-params-editor/ViewParamsSection.module.scss b/apps/client/src/common/components/view-params-editor/ViewParamsSection.module.scss index 720de46b1..9a3a010e2 100644 --- a/apps/client/src/common/components/view-params-editor/ViewParamsSection.module.scss +++ b/apps/client/src/common/components/view-params-editor/ViewParamsSection.module.scss @@ -47,4 +47,4 @@ .hidden { display: none; -} \ No newline at end of file +} diff --git a/apps/client/src/common/components/view-params-editor/ViewParamsSection.tsx b/apps/client/src/common/components/view-params-editor/ViewParamsSection.tsx index 902fe74fb..fe1b73e3c 100644 --- a/apps/client/src/common/components/view-params-editor/ViewParamsSection.tsx +++ b/apps/client/src/common/components/view-params-editor/ViewParamsSection.tsx @@ -1,8 +1,7 @@ -import { IoChevronDown } from 'react-icons/io5'; import { useLocalStorage } from '@mantine/hooks'; +import { IoChevronDown } from 'react-icons/io5'; import { cx } from '../../utils/styleUtils'; - import { OptionTitle } from './constants'; import ParamInput from './ParamInput'; import { type ParamField } from './viewParams.types'; diff --git a/apps/client/src/common/components/view-params-editor/viewParams.utils.ts b/apps/client/src/common/components/view-params-editor/viewParams.utils.ts index c26c63fbc..5f7d4d8f9 100644 --- a/apps/client/src/common/components/view-params-editor/viewParams.utils.ts +++ b/apps/client/src/common/components/view-params-editor/viewParams.utils.ts @@ -1,7 +1,6 @@ import type { CustomFields, ProjectData } from 'ontime-types'; import type { SelectOption } from '../select/Select'; - import type { MultiselectOption, ViewOption } from './viewParams.types'; /** diff --git a/apps/client/src/common/context/AppContext.tsx b/apps/client/src/common/context/AppContext.tsx index 684aafd9d..836ef9116 100644 --- a/apps/client/src/common/context/AppContext.tsx +++ b/apps/client/src/common/context/AppContext.tsx @@ -1,4 +1,4 @@ -import { createContext, PropsWithChildren, useCallback, useEffect, useState } from 'react'; +import { PropsWithChildren, createContext, useCallback, useEffect, useState } from 'react'; import useSettings from '../hooks-query/useSettings'; diff --git a/apps/client/src/common/context/EntryActionsContext.tsx b/apps/client/src/common/context/EntryActionsContext.tsx index 7bb56d80f..983e160de 100644 --- a/apps/client/src/common/context/EntryActionsContext.tsx +++ b/apps/client/src/common/context/EntryActionsContext.tsx @@ -1,4 +1,4 @@ -import { createContext, PropsWithChildren, useContext } from 'react'; +import { PropsWithChildren, createContext, useContext } from 'react'; import { useEntryActions } from '../hooks/useEntryAction'; diff --git a/apps/client/src/common/context/PresetContext.tsx b/apps/client/src/common/context/PresetContext.tsx index 3b5f85920..740813aef 100644 --- a/apps/client/src/common/context/PresetContext.tsx +++ b/apps/client/src/common/context/PresetContext.tsx @@ -1,4 +1,4 @@ -import { createContext } from 'react'; import { URLPreset } from 'ontime-types'; +import { createContext } from 'react'; export const PresetContext = createContext(undefined); diff --git a/apps/client/src/common/hooks-query/useAppVersion.ts b/apps/client/src/common/hooks-query/useAppVersion.ts index 84bcc16fa..c493aebcd 100644 --- a/apps/client/src/common/hooks-query/useAppVersion.ts +++ b/apps/client/src/common/hooks-query/useAppVersion.ts @@ -4,7 +4,7 @@ import { dayInMs } from 'ontime-utils'; import { version } from '../../../../../package.json'; import { isLocalhost } from '../../externals'; import { APP_VERSION } from '../api/constants'; -import { getLatestVersion, HasUpdate } from '../api/external'; +import { HasUpdate, getLatestVersion } from '../api/external'; const placeholder: HasUpdate & { hasUpdates: boolean } = { url: '', version: '', hasUpdates: false }; diff --git a/apps/client/src/common/hooks-query/useProjectList.ts b/apps/client/src/common/hooks-query/useProjectList.ts index 7a88f2cc0..b79324c9b 100644 --- a/apps/client/src/common/hooks-query/useProjectList.ts +++ b/apps/client/src/common/hooks-query/useProjectList.ts @@ -1,6 +1,6 @@ -import { useMemo } from 'react'; import { useQuery } from '@tanstack/react-query'; import { ProjectFile, ProjectFileList, ProjectFileListResponse } from 'ontime-types'; +import { useMemo } from 'react'; import { queryRefetchIntervalSlow } from '../../ontimeConfig'; import { PROJECT_LIST } from '../api/constants'; diff --git a/apps/client/src/common/hooks-query/useProjectRundowns.ts b/apps/client/src/common/hooks-query/useProjectRundowns.ts index 608980106..e0e62ae96 100644 --- a/apps/client/src/common/hooks-query/useProjectRundowns.ts +++ b/apps/client/src/common/hooks-query/useProjectRundowns.ts @@ -3,7 +3,14 @@ import { ProjectRundownsList } from 'ontime-types'; import { queryRefetchIntervalSlow } from '../../ontimeConfig'; import { PROJECT_RUNDOWNS } from '../api/constants'; -import { createRundown, deleteRundown, duplicateRundown, fetchProjectRundownList, loadRundown, renameRundown } from '../api/rundown'; +import { + createRundown, + deleteRundown, + duplicateRundown, + fetchProjectRundownList, + loadRundown, + renameRundown, +} from '../api/rundown'; /** * Project rundowns @@ -30,7 +37,7 @@ export function useMutateProjectRundowns() { ontimeQueryClient.setQueryData(PROJECT_RUNDOWNS, response.data); }, }); - + const { mutateAsync: duplicate } = useMutation({ mutationFn: duplicateRundown, onMutate: () => { @@ -40,7 +47,7 @@ export function useMutateProjectRundowns() { ontimeQueryClient.setQueryData(PROJECT_RUNDOWNS, response.data); }, }); - + const { mutateAsync: rename } = useMutation({ mutationFn: ([rundownId, title]: Parameters) => renameRundown(rundownId, title), onMutate: () => { diff --git a/apps/client/src/common/hooks-query/useRundown.ts b/apps/client/src/common/hooks-query/useRundown.ts index b805edd6d..a35cda70a 100644 --- a/apps/client/src/common/hooks-query/useRundown.ts +++ b/apps/client/src/common/hooks-query/useRundown.ts @@ -1,6 +1,6 @@ -import { useMemo } from 'react'; import { useQuery } from '@tanstack/react-query'; import { EntryId, OntimeEntry, Rundown } from 'ontime-types'; +import { useMemo } from 'react'; import { queryRefetchIntervalSlow } from '../../ontimeConfig'; import { RUNDOWN } from '../api/constants'; diff --git a/apps/client/src/common/hooks-query/useUrlPresets.ts b/apps/client/src/common/hooks-query/useUrlPresets.ts index e9e6bde9c..1d7a46586 100644 --- a/apps/client/src/common/hooks-query/useUrlPresets.ts +++ b/apps/client/src/common/hooks-query/useUrlPresets.ts @@ -1,6 +1,6 @@ -import { useMemo } from 'react'; import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; import { OntimeView, URLPreset } from 'ontime-types'; +import { useMemo } from 'react'; import { queryRefetchIntervalSlow } from '../../ontimeConfig'; import { URL_PRESETS } from '../api/constants'; diff --git a/apps/client/src/common/hooks/useClientPath.ts b/apps/client/src/common/hooks/useClientPath.ts index 0f0ae3e1d..46abb74d4 100644 --- a/apps/client/src/common/hooks/useClientPath.ts +++ b/apps/client/src/common/hooks/useClientPath.ts @@ -1,11 +1,10 @@ +import { MessageTag } from 'ontime-types'; import { useEffect } from 'react'; import { useLocation, useNavigate } from 'react-router'; -import { MessageTag } from 'ontime-types'; import { useShallow } from 'zustand/shallow'; import { useClientStore } from '../stores/clientStore'; import { sendSocket } from '../utils/socket'; - import { useIsOnline } from './useSocket'; export const useClientPath = () => { diff --git a/apps/client/src/common/hooks/useEntryAction.ts b/apps/client/src/common/hooks/useEntryAction.ts index a4600aedb..93bb7d094 100644 --- a/apps/client/src/common/hooks/useEntryAction.ts +++ b/apps/client/src/common/hooks/useEntryAction.ts @@ -1,10 +1,7 @@ -import { useCallback, useMemo } from 'react'; import { useMutation, useQueryClient } from '@tanstack/react-query'; import { EntryId, InsertOptions, - isOntimeEvent, - isOntimeGroup, MaybeString, OntimeDelay, OntimeEntry, @@ -16,8 +13,11 @@ import { SupportedEntry, TimeField, TimeStrategy, + isOntimeEvent, + isOntimeGroup, } from 'ontime-types'; import { + MILLIS_PER_SECOND, addToRundown, createDelay, createEvent, @@ -26,22 +26,22 @@ import { dayInMs, generateId, getInsertAfterId, - MILLIS_PER_SECOND, parseUserTime, resolveInsertParent, swapEventData, } from 'ontime-utils'; +import { useCallback, useMemo } from 'react'; import { moveDown, moveUp, orderEntries } from '../../features/rundown/rundown.utils'; import { RUNDOWN } from '../api/constants'; import { + ReorderEntry, deleteEntries, patchReorderEntry, postAddEntry, postCloneEntry, putBatchEditEvents, putEditEntry, - ReorderEntry, requestApplyDelay, requestDeleteAll, requestEventSwap, diff --git a/apps/client/src/common/hooks/useFollowComponent.ts b/apps/client/src/common/hooks/useFollowComponent.ts index dafdcdc58..a757b2e9c 100644 --- a/apps/client/src/common/hooks/useFollowComponent.ts +++ b/apps/client/src/common/hooks/useFollowComponent.ts @@ -1,5 +1,5 @@ -import { RefObject, useCallback, useEffect } from 'react'; import { MaybeString } from 'ontime-types'; +import { RefObject, useCallback, useEffect } from 'react'; function scrollToComponent( componentRef: RefObject, diff --git a/apps/client/src/common/hooks/useHorizontalFollowComponent.ts b/apps/client/src/common/hooks/useHorizontalFollowComponent.ts index 12e66ee78..806254394 100644 --- a/apps/client/src/common/hooks/useHorizontalFollowComponent.ts +++ b/apps/client/src/common/hooks/useHorizontalFollowComponent.ts @@ -1,5 +1,5 @@ -import { RefObject, useCallback, useEffect } from 'react'; import { EntryId } from 'ontime-types'; +import { RefObject, useCallback, useEffect } from 'react'; function scrollToComponent( componentRef: RefObject | null, diff --git a/apps/client/src/common/hooks/useIsMobileDevice.ts b/apps/client/src/common/hooks/useIsMobileDevice.ts index b020d05c0..f66d33815 100644 --- a/apps/client/src/common/hooks/useIsMobileDevice.ts +++ b/apps/client/src/common/hooks/useIsMobileDevice.ts @@ -1,5 +1,5 @@ -import { useMemo } from 'react'; import { useOs, useViewportSize } from '@mantine/hooks'; +import { useMemo } from 'react'; export function useIsMobileDevice(): boolean { const { width } = useViewportSize(); diff --git a/apps/client/src/common/hooks/useIsMobileScreen.ts b/apps/client/src/common/hooks/useIsMobileScreen.ts index 71257441e..c65bac33d 100644 --- a/apps/client/src/common/hooks/useIsMobileScreen.ts +++ b/apps/client/src/common/hooks/useIsMobileScreen.ts @@ -1,5 +1,5 @@ -import { useMemo } from 'react'; import { useViewportSize } from '@mantine/hooks'; +import { useMemo } from 'react'; export function useIsMobileScreen(): boolean { const { width } = useViewportSize(); diff --git a/apps/client/src/common/hooks/useIsSmallDevice.ts b/apps/client/src/common/hooks/useIsSmallDevice.ts index 4d0b4e7e6..35e69657a 100644 --- a/apps/client/src/common/hooks/useIsSmallDevice.ts +++ b/apps/client/src/common/hooks/useIsSmallDevice.ts @@ -1,5 +1,5 @@ -import { useMemo } from 'react'; import { useOs, useViewportSize } from '@mantine/hooks'; +import { useMemo } from 'react'; export function useIsSmallDevice(): boolean { const { width } = useViewportSize(); diff --git a/apps/client/src/common/hooks/useIsSmallScreen.ts b/apps/client/src/common/hooks/useIsSmallScreen.ts index 08eb7f27c..2a7bc49b8 100644 --- a/apps/client/src/common/hooks/useIsSmallScreen.ts +++ b/apps/client/src/common/hooks/useIsSmallScreen.ts @@ -1,5 +1,5 @@ -import { useMemo } from 'react'; import { useViewportSize } from '@mantine/hooks'; +import { useMemo } from 'react'; export function useIsSmallScreen(): boolean { const { width } = useViewportSize(); diff --git a/apps/client/src/common/stores/editorSettings.ts b/apps/client/src/common/stores/editorSettings.ts index 8a102f4c9..5a678d39e 100644 --- a/apps/client/src/common/stores/editorSettings.ts +++ b/apps/client/src/common/stores/editorSettings.ts @@ -1,5 +1,5 @@ -import { EndAction, TimerType, TimeStrategy } from 'ontime-types'; -import { validateEndAction, validateTimerType, validateTimeStrategy } from 'ontime-utils'; +import { EndAction, TimeStrategy, TimerType } from 'ontime-types'; +import { validateEndAction, validateTimeStrategy, validateTimerType } from 'ontime-utils'; import { create } from 'zustand'; import { booleanFromLocalStorage } from '../utils/localStorage'; diff --git a/apps/client/src/common/stores/logger.ts b/apps/client/src/common/stores/logger.ts index ee8f04832..13d3b348e 100644 --- a/apps/client/src/common/stores/logger.ts +++ b/apps/client/src/common/stores/logger.ts @@ -1,6 +1,6 @@ -import { useCallback } from 'react'; import { Log, LogLevel, LogOrigin, MessageTag } from 'ontime-types'; import { generateId, millisToString } from 'ontime-utils'; +import { useCallback } from 'react'; import { useStore } from 'zustand'; import { createStore } from 'zustand/vanilla'; diff --git a/apps/client/src/common/stores/runtime.ts b/apps/client/src/common/stores/runtime.ts index e8a291932..0e8951d48 100644 --- a/apps/client/src/common/stores/runtime.ts +++ b/apps/client/src/common/stores/runtime.ts @@ -1,5 +1,5 @@ -import isEqual from 'react-fast-compare'; import { RuntimeStore, runtimeStorePlaceholder } from 'ontime-types'; +import isEqual from 'react-fast-compare'; import { createWithEqualityFn, useStoreWithEqualityFn } from 'zustand/traditional'; const deepCompare = (a: T, b: T) => isEqual(a, b); diff --git a/apps/client/src/common/utils/__tests__/styleUtils.module.scss b/apps/client/src/common/utils/__tests__/styleUtils.module.scss index f15ae3fd8..2b7de5b62 100644 --- a/apps/client/src/common/utils/__tests__/styleUtils.module.scss +++ b/apps/client/src/common/utils/__tests__/styleUtils.module.scss @@ -1,2 +1,4 @@ -.test {} -.another {} +.test { +} +.another { +} diff --git a/apps/client/src/common/utils/__tests__/time.test.ts b/apps/client/src/common/utils/__tests__/time.test.ts index be11e0ded..3334055c6 100644 --- a/apps/client/src/common/utils/__tests__/time.test.ts +++ b/apps/client/src/common/utils/__tests__/time.test.ts @@ -3,15 +3,19 @@ import { MILLIS_PER_HOUR, MILLIS_PER_MINUTE, MILLIS_PER_SECOND } from 'ontime-ut import { formatDuration, formatTime, nowInMillis } from '../time'; describe('nowInMillis()', () => { + afterEach(() => { + vi.useRealTimers(); + }); + it('should return the current time in milliseconds', () => { const mockDate = new Date(2022, 1, 1, 13, 0, 0); // This date corresponds to 13:00:00 const expectedMillis = 13 * 60 * 60 * 1000; - const dateSpy = vi.spyOn(global, 'Date').mockImplementation(() => mockDate as any); + vi.useFakeTimers(); + vi.setSystemTime(mockDate); const result = nowInMillis(); expect(result).toBe(expectedMillis); - dateSpy.mockRestore(); }); }); diff --git a/apps/client/src/common/utils/__tests__/urlPresets.test.ts b/apps/client/src/common/utils/__tests__/urlPresets.test.ts index b11db2623..01d2abe86 100644 --- a/apps/client/src/common/utils/__tests__/urlPresets.test.ts +++ b/apps/client/src/common/utils/__tests__/urlPresets.test.ts @@ -1,5 +1,5 @@ -import { Path, resolvePath } from 'react-router'; import { OntimeView, URLPreset } from 'ontime-types'; +import { Path, resolvePath } from 'react-router'; import { arePathsEquivalent, @@ -231,11 +231,11 @@ describe('generateUrlPresetOptions', () => { }); it('throws on invalid URL', () => { - expect(() => generateUrlPresetOptions('test', 'invalid-url')).toThrow(); + expect(() => generateUrlPresetOptions('test', 'invalid-url')).toThrow('Invalid target view:'); }); it('throws on invalid route', () => { - expect(() => generateUrlPresetOptions('test', 'www.getontime.no/somethingelse/')).toThrow(); + expect(() => generateUrlPresetOptions('test', 'www.getontime.no/somethingelse/')).toThrow('Invalid target view:'); }); }); diff --git a/apps/client/src/common/utils/dateConfig.ts b/apps/client/src/common/utils/dateConfig.ts index 780f3b653..38e1e19c8 100644 --- a/apps/client/src/common/utils/dateConfig.ts +++ b/apps/client/src/common/utils/dateConfig.ts @@ -1,5 +1,5 @@ import { MaybeNumber } from 'ontime-types'; -import { formatFromMillis, MILLIS_PER_HOUR, MILLIS_PER_MINUTE } from 'ontime-utils'; +import { MILLIS_PER_HOUR, MILLIS_PER_MINUTE, formatFromMillis } from 'ontime-utils'; /** * Parses a value in millis to a string which encodes a delay diff --git a/apps/client/src/common/utils/linkUtils.ts b/apps/client/src/common/utils/linkUtils.ts index db2b0707c..d23a21133 100644 --- a/apps/client/src/common/utils/linkUtils.ts +++ b/apps/client/src/common/utils/linkUtils.ts @@ -2,14 +2,22 @@ import type { MouseEvent } from 'react'; import { baseURI, serverURL } from '../../externals'; +type ElectronWindow = Window & { + process?: { type?: string }; + ipcRenderer?: { + send: (channel: string, args?: string | object) => void; + }; +}; + /** * Open an external URLs: specifically for a electron / browser case * If electron: ask main process to call a new browser window * If browser: open in new tab */ export function openLink(url: string) { - if (window.process?.type === 'renderer') { - window.ipcRenderer.send('send-to-link', url); + const electronWindow = window as ElectronWindow; + if (electronWindow.process?.type === 'renderer' && electronWindow.ipcRenderer) { + electronWindow.ipcRenderer.send('send-to-link', url); } else { window.open(url); } diff --git a/apps/client/src/common/utils/rundownMetadata.ts b/apps/client/src/common/utils/rundownMetadata.ts index 8d94f38f5..5e410bae0 100644 --- a/apps/client/src/common/utils/rundownMetadata.ts +++ b/apps/client/src/common/utils/rundownMetadata.ts @@ -1,7 +1,4 @@ import { - isOntimeEvent, - isOntimeGroup, - isPlayableEvent, MaybeString, OntimeDelay, OntimeEntry, @@ -9,6 +6,9 @@ import { OntimeMilestone, PlayableEvent, Rundown, + isOntimeEvent, + isOntimeGroup, + isPlayableEvent, } from 'ontime-types'; import { checkIsNextDay, isNewLatest } from 'ontime-utils'; @@ -151,13 +151,13 @@ function processEntry( if (isPlayableEvent(entry)) { processedData.isNextDay = checkIsNextDay(entry, processedData.previousEvent); - + if (!processedData.isPast && !processedData.isLoaded) { /** * isLinkToLoaded is a chain value that we maintain until we * a) find an unlinked event * b) find a countToEnd event - */ + */ processedData.totalGap += entry.gap; processedData.isLinkedToLoaded = entry.linkStart && !processedData.previousEvent?.countToEnd && processedData.isLinkedToLoaded; diff --git a/apps/client/src/common/utils/time.ts b/apps/client/src/common/utils/time.ts index fc5bb6c9f..392ab6320 100644 --- a/apps/client/src/common/utils/time.ts +++ b/apps/client/src/common/utils/time.ts @@ -1,17 +1,16 @@ import { MaybeNumber, OntimeEvent, Settings, TimeFormat } from 'ontime-types'; import { - formatFromMillis, - getExpectedStart, MILLIS_PER_HOUR, MILLIS_PER_MINUTE, MILLIS_PER_SECOND, + formatFromMillis, + getExpectedStart, } from 'ontime-utils'; import { FORMAT_12, FORMAT_24 } from '../../viewerConfig'; import { APP_SETTINGS } from '../api/constants'; import { useExpectedStartData } from '../hooks/useSocket'; import { ontimeQueryClient } from '../queryClient'; - import { ExtendedEntry } from './rundownMetadata'; /** diff --git a/apps/client/src/common/utils/urlPresets.ts b/apps/client/src/common/utils/urlPresets.ts index 8f4089497..5479c8dc8 100644 --- a/apps/client/src/common/utils/urlPresets.ts +++ b/apps/client/src/common/utils/urlPresets.ts @@ -1,6 +1,6 @@ -import { Path, resolvePath } from 'react-router'; import { OntimeView, OntimeViewPresettable, URLPreset } from 'ontime-types'; import { checkRegex } from 'ontime-utils'; +import { Path, resolvePath } from 'react-router'; /** * Validates a preset against defined parameters diff --git a/apps/client/src/declarations/declaration.d.ts b/apps/client/src/declarations/declaration.d.ts index 94933ffae..08bfc0861 100644 --- a/apps/client/src/declarations/declaration.d.ts +++ b/apps/client/src/declarations/declaration.d.ts @@ -5,6 +5,11 @@ declare module '*.scss' { export default content; } +declare module '*.css' { + const content: Record; + export default content; +} + type ListenerType = (event: 'string', args: unknown[]) => void; declare global { diff --git a/apps/client/src/externals.ts b/apps/client/src/externals.ts index f8fa3d983..824245826 100644 --- a/apps/client/src/externals.ts +++ b/apps/client/src/externals.ts @@ -23,7 +23,7 @@ export const isProduction = import.meta.env.PROD; export const isDev = import.meta.env.DEV; export const currentHostName = window.location.hostname; export const isLocalhost = currentHostName === 'localhost' || currentHostName === '127.0.0.1'; -export const isOntimeCloud = document.querySelector('base')?.hasAttribute('data-is-cloud') +export const isOntimeCloud = document.querySelector('base')?.hasAttribute('data-is-cloud'); export const isTouchDevice = 'ontouchstart' in window || navigator.maxTouchPoints > 0; export const supportsFullscreen = document.fullscreenEnabled; diff --git a/apps/client/src/features/app-settings/AppSettings.tsx b/apps/client/src/features/app-settings/AppSettings.tsx index 90e4931cd..b3da5d21c 100644 --- a/apps/client/src/features/app-settings/AppSettings.tsx +++ b/apps/client/src/features/app-settings/AppSettings.tsx @@ -1,7 +1,8 @@ import { ErrorBoundary } from '@sentry/react'; import { useKeyDown } from '../../common/hooks/useKeyDown'; - +import PanelContent from './panel-content/PanelContent'; +import PanelList from './panel-list/PanelList'; import AboutPanel from './panel/about-panel/AboutPanel'; import AutomationPanel from './panel/automations-panel/AutomationPanel'; import FeaturePanel from './panel/feature-panel/FeaturePanel'; @@ -10,8 +11,6 @@ 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 PanelContent from './panel-content/PanelContent'; -import PanelList from './panel-list/PanelList'; import useAppSettingsNavigation from './useAppSettingsNavigation'; import style from './AppSettings.module.scss'; 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 5ad62f94e..c2d334d10 100644 --- a/apps/client/src/features/app-settings/panel-list/PanelList.tsx +++ b/apps/client/src/features/app-settings/panel-list/PanelList.tsx @@ -59,7 +59,9 @@ function PanelListItem(props: PanelListItemProps) { key={panel.id} onClick={() => setLocation(panel.id as SettingsOptionId)} onKeyDown={(event) => { - isKeyEnter(event) && setLocation(panel.id as SettingsOptionId); + if (isKeyEnter(event)) { + setLocation(panel.id as SettingsOptionId); + } }} className={classes} tabIndex={0} @@ -75,7 +77,9 @@ function PanelListItem(props: PanelListItemProps) { key={secondary.id + index} onClick={() => setLocation(secondary.id as SettingsOptionId)} onKeyDown={(event) => { - isKeyEnter(event) && setLocation(secondary.id as SettingsOptionId); + if (isKeyEnter(event)) { + setLocation(secondary.id as SettingsOptionId); + } }} className={secondaryClasses} role='button' diff --git a/apps/client/src/features/app-settings/panel/about-panel/AboutPanel.tsx b/apps/client/src/features/app-settings/panel/about-panel/AboutPanel.tsx index 47ff4ce79..8039595ee 100644 --- a/apps/client/src/features/app-settings/panel/about-panel/AboutPanel.tsx +++ b/apps/client/src/features/app-settings/panel/about-panel/AboutPanel.tsx @@ -9,7 +9,6 @@ import { websiteUrl, } from '../../../../externals'; import * as Panel from '../../panel-utils/PanelUtils'; - import AppVersion from './AppVersion'; export default function AboutPanel() { 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 5ef01c891..6fc74e8d3 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,16 +1,16 @@ -import { useEffect, useMemo } from 'react'; -import { useFieldArray, useForm } from 'react-hook-form'; -import { IoAdd, IoTrash } from 'react-icons/io5'; import { Automation, AutomationDTO, HTTPOutput, - isHTTPOutput, - isOntimeAction, - isOSCOutput, - OntimeAction, OSCOutput, + OntimeAction, + isHTTPOutput, + isOSCOutput, + isOntimeAction, } from 'ontime-types'; +import { useEffect, useMemo } from 'react'; +import { useFieldArray, useForm } from 'react-hook-form'; +import { IoAdd, IoTrash } from 'react-icons/io5'; import { addAutomation, editAutomation, testOutput } from '../../../../common/api/automation'; import { maybeAxiosError } from '../../../../common/api/utils'; @@ -27,10 +27,9 @@ import useCustomFields from '../../../../common/hooks-query/useCustomFields'; import { preventEscape } from '../../../../common/utils/keyEvent'; import { startsWithHttp } from '../../../../common/utils/regex'; import * as Panel from '../../panel-utils/PanelUtils'; - -import TemplateInput from './template-input/TemplateInput'; import { isAutomation, makeFieldList } from './automationUtils'; import OntimeActionForm from './OntimeActionForm'; +import TemplateInput from './template-input/TemplateInput'; import style from './AutomationForm.module.scss'; diff --git a/apps/client/src/features/app-settings/panel/automations-panel/AutomationPanel.tsx b/apps/client/src/features/app-settings/panel/automations-panel/AutomationPanel.tsx index 3345a561f..7ec7d591c 100644 --- a/apps/client/src/features/app-settings/panel/automations-panel/AutomationPanel.tsx +++ b/apps/client/src/features/app-settings/panel/automations-panel/AutomationPanel.tsx @@ -1,8 +1,7 @@ -import useScrollIntoView from '../../../../common/hooks/useScrollIntoView'; import useAutomationSettings from '../../../../common/hooks-query/useAutomationSettings'; +import useScrollIntoView from '../../../../common/hooks/useScrollIntoView'; import type { PanelBaseProps } from '../../panel-list/PanelList'; import * as Panel from '../../panel-utils/PanelUtils'; - import AutomationSettingsForm from './AutomationSettingsForm'; import AutomationsList from './AutomationsList'; import TriggersList from './TriggersList'; diff --git a/apps/client/src/features/app-settings/panel/automations-panel/AutomationsList.tsx b/apps/client/src/features/app-settings/panel/automations-panel/AutomationsList.tsx index 630957c22..5c0e848e2 100644 --- a/apps/client/src/features/app-settings/panel/automations-panel/AutomationsList.tsx +++ b/apps/client/src/features/app-settings/panel/automations-panel/AutomationsList.tsx @@ -1,6 +1,6 @@ +import { AutomationDTO, NormalisedAutomation } from 'ontime-types'; import { Fragment, useState } from 'react'; import { IoAdd, IoPencil, IoTrash } from 'react-icons/io5'; -import { AutomationDTO, NormalisedAutomation } from 'ontime-types'; import { deleteAutomation } from '../../../../common/api/automation'; import { maybeAxiosError } from '../../../../common/api/utils'; @@ -9,7 +9,6 @@ import IconButton from '../../../../common/components/buttons/IconButton'; import Tag from '../../../../common/components/tag/Tag'; import useAutomationSettings from '../../../../common/hooks-query/useAutomationSettings'; import * as Panel from '../../panel-utils/PanelUtils'; - import AutomationForm from './AutomationForm'; const automationPlaceholder: AutomationDTO = { 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 9f3e81143..3318789f2 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,6 +1,6 @@ +import { AutomationDTO, OntimeAction, OntimeActionKey, SecondarySource } from 'ontime-types'; import { PropsWithChildren, useState } from 'react'; import { UseFormRegister, UseFormSetValue, UseFormWatch } from 'react-hook-form'; -import { AutomationDTO, OntimeAction, OntimeActionKey, SecondarySource } from 'ontime-types'; import Input from '../../../../common/components/input/input/Input'; import Select from '../../../../common/components/select/Select'; diff --git a/apps/client/src/features/app-settings/panel/automations-panel/TriggerForm.tsx b/apps/client/src/features/app-settings/panel/automations-panel/TriggerForm.tsx index cab2452bd..49cee5a64 100644 --- a/apps/client/src/features/app-settings/panel/automations-panel/TriggerForm.tsx +++ b/apps/client/src/features/app-settings/panel/automations-panel/TriggerForm.tsx @@ -1,6 +1,6 @@ +import { NormalisedAutomation, TimerLifeCycle, TriggerDTO } from 'ontime-types'; import { useEffect } from 'react'; import { useForm } from 'react-hook-form'; -import { NormalisedAutomation, TimerLifeCycle, TriggerDTO } from 'ontime-types'; import { addTrigger, editTrigger } from '../../../../common/api/automation'; import { maybeAxiosError } from '../../../../common/api/utils'; @@ -9,7 +9,6 @@ import Input from '../../../../common/components/input/input/Input'; import Select from '../../../../common/components/select/Select'; import { preventEscape } from '../../../../common/utils/keyEvent'; import * as Panel from '../../panel-utils/PanelUtils'; - import { cycles } from './automationUtils'; interface TriggerFormProps { 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 531994cc6..80712cfef 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,13 +1,12 @@ +import { NormalisedAutomation, Trigger } from 'ontime-types'; import { Fragment, useMemo, useState } from 'react'; import { IoAdd } from 'react-icons/io5'; -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'; - import { checkDuplicates } from './automationUtils'; import AutomationForm from './TriggerForm'; import TriggersListItem from './TriggersListItem'; 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 cadd0127c..64f01f44d 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,11 +1,10 @@ +import { NormalisedAutomation, TimerLifeCycle } from 'ontime-types'; import { useState } from 'react'; import { IoPencil, IoTrash, IoWarningOutline } from 'react-icons/io5'; -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'; - import { cycles } from './automationUtils'; import AutomationForm from './TriggerForm'; 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 0992f3239..7f9bb16c2 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,9 +1,8 @@ -import { forwardRef, useMemo, useState } from 'react'; import { mergeRefs, useClickOutside } from '@mantine/hooks'; +import { forwardRef, useMemo, useState } from 'react'; import Input, { type InputProps } from '../../../../../common/components/input/input/Input'; import useCustomFields from '../../../../../common/hooks-query/useCustomFields'; - import { makeAutoCompleteList, matchRemaining, selectFromLastTemplate } from './templateInput.utils'; import style from './TemplateInput.module.scss'; 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 index d75148fcb..f88024a3e 100644 --- a/apps/client/src/features/app-settings/panel/feature-panel/FeaturePanel.tsx +++ b/apps/client/src/features/app-settings/panel/feature-panel/FeaturePanel.tsx @@ -4,7 +4,6 @@ import GenerateLinkFormExport from '../../../sharing/GenerateLinkFormExport'; import type { PanelBaseProps } from '../../panel-list/PanelList'; import * as Panel from '../../panel-utils/PanelUtils'; import InfoNif from '../network-panel/NetworkInterfaces'; - import ReportSettings from './ReportSettings'; import URLPresets from './URLPresets'; diff --git a/apps/client/src/features/app-settings/panel/feature-panel/ReportSettings.tsx b/apps/client/src/features/app-settings/panel/feature-panel/ReportSettings.tsx index b1ba675e6..7dafb2a65 100644 --- a/apps/client/src/features/app-settings/panel/feature-panel/ReportSettings.tsx +++ b/apps/client/src/features/app-settings/panel/feature-panel/ReportSettings.tsx @@ -9,7 +9,6 @@ import useRundown from '../../../../common/hooks-query/useRundown'; import { cx } from '../../../../common/utils/styleUtils'; import { formatTime } from '../../../../common/utils/time'; import * as Panel from '../../panel-utils/PanelUtils'; - import { CombinedReport, getCombinedReport, makeReportCSV } from './reportSettings.utils'; import style from './ReportSettings.module.scss'; diff --git a/apps/client/src/features/app-settings/panel/feature-panel/URLPresets.tsx b/apps/client/src/features/app-settings/panel/feature-panel/URLPresets.tsx index 82222ad98..1c4d0674f 100644 --- a/apps/client/src/features/app-settings/panel/feature-panel/URLPresets.tsx +++ b/apps/client/src/features/app-settings/panel/feature-panel/URLPresets.tsx @@ -1,6 +1,6 @@ +import { URLPreset } from 'ontime-types'; import { useState } from 'react'; import { IoAdd, IoOpenOutline, IoPencil, IoTrash } from 'react-icons/io5'; -import { URLPreset } from 'ontime-types'; import Button from '../../../../common/components/buttons/Button'; import IconButton from '../../../../common/components/buttons/IconButton'; @@ -11,7 +11,6 @@ import Tag from '../../../../common/components/tag/Tag'; import useUrlPresets, { useUpdateUrlPreset } from '../../../../common/hooks-query/useUrlPresets'; import { handleLinks } from '../../../../common/utils/linkUtils'; import * as Panel from '../../panel-utils/PanelUtils'; - import URLPresetForm from './composite/URLPresetForm'; type FormState = { diff --git a/apps/client/src/features/app-settings/panel/feature-panel/composite/URLPresetForm.module.scss b/apps/client/src/features/app-settings/panel/feature-panel/composite/URLPresetForm.module.scss index db630a5c9..f05f5abff 100644 --- a/apps/client/src/features/app-settings/panel/feature-panel/composite/URLPresetForm.module.scss +++ b/apps/client/src/features/app-settings/panel/feature-panel/composite/URLPresetForm.module.scss @@ -6,4 +6,4 @@ display: flex; flex-direction: column; gap: 1rem; -} \ No newline at end of file +} diff --git a/apps/client/src/features/app-settings/panel/feature-panel/composite/URLPresetForm.tsx b/apps/client/src/features/app-settings/panel/feature-panel/composite/URLPresetForm.tsx index 168e6e8b9..d2fcebd9a 100644 --- a/apps/client/src/features/app-settings/panel/feature-panel/composite/URLPresetForm.tsx +++ b/apps/client/src/features/app-settings/panel/feature-panel/composite/URLPresetForm.tsx @@ -1,6 +1,6 @@ +import { OntimeView, OntimeViewPresettable, URLPreset } from 'ontime-types'; import { useEffect, useRef } from 'react'; import { useForm } from 'react-hook-form'; -import { OntimeView, OntimeViewPresettable, URLPreset } from 'ontime-types'; import { maybeAxiosError, unwrapError } from '../../../../../common/api/utils'; import Button from '../../../../../common/components/buttons/Button'; diff --git a/apps/client/src/features/app-settings/panel/feature-panel/reportSettings.utils.ts b/apps/client/src/features/app-settings/panel/feature-panel/reportSettings.utils.ts index 11b25c1b0..75de3c57b 100644 --- a/apps/client/src/features/app-settings/panel/feature-panel/reportSettings.utils.ts +++ b/apps/client/src/features/app-settings/panel/feature-panel/reportSettings.utils.ts @@ -1,4 +1,4 @@ -import { EntryId, isOntimeEvent, MaybeNumber, OntimeReport, RundownEntries } from 'ontime-types'; +import { EntryId, MaybeNumber, OntimeReport, RundownEntries, isOntimeEvent } from 'ontime-types'; import { makeCSVFromArrayOfArrays } from '../../../../common/utils/csv'; import { formatTime } from '../../../../common/utils/time'; diff --git a/apps/client/src/features/app-settings/panel/manage-panel/CustomFields.tsx b/apps/client/src/features/app-settings/panel/manage-panel/CustomFields.tsx index a4d3c21fd..fdcfed41e 100644 --- a/apps/client/src/features/app-settings/panel/manage-panel/CustomFields.tsx +++ b/apps/client/src/features/app-settings/panel/manage-panel/CustomFields.tsx @@ -1,6 +1,6 @@ +import { CustomField, CustomFieldKey } from 'ontime-types'; import { useState } from 'react'; import { IoAdd } from 'react-icons/io5'; -import { CustomField, CustomFieldKey } from 'ontime-types'; import { deleteCustomField, editCustomField, postCustomField } from '../../../../common/api/customFields'; import Button from '../../../../common/components/buttons/Button'; @@ -10,7 +10,6 @@ import ExternalLink from '../../../../common/components/link/external-link/Exter import useCustomFields from '../../../../common/hooks-query/useCustomFields'; import { customFieldsDocsUrl } from '../../../../externals'; import * as Panel from '../../panel-utils/PanelUtils'; - import CustomFieldEntry from './composite/CustomFieldEntry'; import CustomFieldForm from './composite/CustomFieldForm'; 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 index aca6a5ccc..1f4cadc80 100644 --- a/apps/client/src/features/app-settings/panel/manage-panel/ManagePanel.tsx +++ b/apps/client/src/features/app-settings/panel/manage-panel/ManagePanel.tsx @@ -1,11 +1,10 @@ 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'; +import SourcesPanel from './sources-panel/SourcesPanel'; export default function ManagePanel({ location }: PanelBaseProps) { const defaultsRef = useScrollIntoView('defaults', location); diff --git a/apps/client/src/features/app-settings/panel/manage-panel/ManageRundowns.tsx b/apps/client/src/features/app-settings/panel/manage-panel/ManageRundowns.tsx index 0d453283d..c3c6562b9 100644 --- a/apps/client/src/features/app-settings/panel/manage-panel/ManageRundowns.tsx +++ b/apps/client/src/features/app-settings/panel/manage-panel/ManageRundowns.tsx @@ -1,3 +1,4 @@ +import { useDisclosure } from '@mantine/hooks'; import { useState } from 'react'; import { IoAdd, @@ -8,7 +9,6 @@ import { IoPencilOutline, IoTrash, } from 'react-icons/io5'; -import { useDisclosure } from '@mantine/hooks'; import { downloadAsExcel } from '../../../../common/api/excel'; import { maybeAxiosError } from '../../../../common/api/utils'; @@ -20,7 +20,6 @@ import Tag from '../../../../common/components/tag/Tag'; import { useMutateProjectRundowns, useProjectRundowns } from '../../../../common/hooks-query/useProjectRundowns'; import { cx } from '../../../../common/utils/styleUtils'; import * as Panel from '../../panel-utils/PanelUtils'; - import RundownRenameForm from './composite/RundownRenameForm'; import { ManageRundownForm } from './ManageRundownForm'; diff --git a/apps/client/src/features/app-settings/panel/manage-panel/RundownDefaultSettings.tsx b/apps/client/src/features/app-settings/panel/manage-panel/RundownDefaultSettings.tsx index b7557ad91..0e8f7c4cd 100644 --- a/apps/client/src/features/app-settings/panel/manage-panel/RundownDefaultSettings.tsx +++ b/apps/client/src/features/app-settings/panel/manage-panel/RundownDefaultSettings.tsx @@ -1,4 +1,4 @@ -import { EndAction, TimerType, TimeStrategy } from 'ontime-types'; +import { EndAction, TimeStrategy, TimerType } from 'ontime-types'; import { parseUserTime } from 'ontime-utils'; import TimeInput from '../../../../common/components/input/time-input/TimeInput'; diff --git a/apps/client/src/features/app-settings/panel/manage-panel/composite/CustomFieldEntry.tsx b/apps/client/src/features/app-settings/panel/manage-panel/composite/CustomFieldEntry.tsx index 1b2857186..010230677 100644 --- a/apps/client/src/features/app-settings/panel/manage-panel/composite/CustomFieldEntry.tsx +++ b/apps/client/src/features/app-settings/panel/manage-panel/composite/CustomFieldEntry.tsx @@ -1,13 +1,12 @@ +import { CustomField, CustomFieldKey } from 'ontime-types'; import { useState } from 'react'; import { IoPencil, IoTrash } from 'react-icons/io5'; -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'; import * as Panel from '../../../panel-utils/PanelUtils'; - import CustomFieldForm from './CustomFieldForm'; import style from '../ManagePanel.module.scss'; diff --git a/apps/client/src/features/app-settings/panel/manage-panel/composite/CustomFieldForm.tsx b/apps/client/src/features/app-settings/panel/manage-panel/composite/CustomFieldForm.tsx index cbb5884c4..f5a27d852 100644 --- a/apps/client/src/features/app-settings/panel/manage-panel/composite/CustomFieldForm.tsx +++ b/apps/client/src/features/app-settings/panel/manage-panel/composite/CustomFieldForm.tsx @@ -1,7 +1,7 @@ -import { useEffect, useState } from 'react'; -import { useForm } from 'react-hook-form'; import { CustomField } from 'ontime-types'; import { checkRegex, customFieldLabelToKey } from 'ontime-utils'; +import { useEffect, useState } from 'react'; +import { useForm } from 'react-hook-form'; import { maybeAxiosError } from '../../../../../common/api/utils'; import Button from '../../../../../common/components/buttons/Button'; diff --git a/apps/client/src/features/app-settings/panel/manage-panel/composite/RundownRenameForm.tsx b/apps/client/src/features/app-settings/panel/manage-panel/composite/RundownRenameForm.tsx index d541a57fc..be37c9a5e 100644 --- a/apps/client/src/features/app-settings/panel/manage-panel/composite/RundownRenameForm.tsx +++ b/apps/client/src/features/app-settings/panel/manage-panel/composite/RundownRenameForm.tsx @@ -1,6 +1,6 @@ +import { checkRegex } from 'ontime-utils'; import { useEffect } from 'react'; import { useForm } from 'react-hook-form'; -import { checkRegex } from 'ontime-utils'; import { maybeAxiosError } from '../../../../../common/api/utils'; import Button from '../../../../../common/components/buttons/Button'; diff --git a/apps/client/src/features/app-settings/panel/manage-panel/sources-panel/GSheetInfo.tsx b/apps/client/src/features/app-settings/panel/manage-panel/sources-panel/GSheetInfo.tsx index 96388cf40..197c79a17 100644 --- a/apps/client/src/features/app-settings/panel/manage-panel/sources-panel/GSheetInfo.tsx +++ b/apps/client/src/features/app-settings/panel/manage-panel/sources-panel/GSheetInfo.tsx @@ -6,9 +6,8 @@ const googleSheetDocsUrl = 'https://docs.getontime.no/features/import-spreadshee export default function GSheetInfo() { return ( - Ontime can import data from spreadsheets by:
- - importing the spreadsheet file in Ontime
- - synchronising your project with a Google Sheet + Ontime can import data from spreadsheets by:
- importing the spreadsheet file in Ontime
- + synchronising your project with a Google Sheet

To synchronise with a Google Sheet, you will need to allow Ontime to authenticate with your Google account. diff --git a/apps/client/src/features/app-settings/panel/manage-panel/sources-panel/GSheetSetup.tsx b/apps/client/src/features/app-settings/panel/manage-panel/sources-panel/GSheetSetup.tsx index 49b706828..4278cff77 100644 --- a/apps/client/src/features/app-settings/panel/manage-panel/sources-panel/GSheetSetup.tsx +++ b/apps/client/src/features/app-settings/panel/manage-panel/sources-panel/GSheetSetup.tsx @@ -8,7 +8,6 @@ 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'; diff --git a/apps/client/src/features/app-settings/panel/manage-panel/sources-panel/ImportReview.tsx b/apps/client/src/features/app-settings/panel/manage-panel/sources-panel/ImportReview.tsx index 5a7ac166f..e49ce11f1 100644 --- a/apps/client/src/features/app-settings/panel/manage-panel/sources-panel/ImportReview.tsx +++ b/apps/client/src/features/app-settings/panel/manage-panel/sources-panel/ImportReview.tsx @@ -1,12 +1,11 @@ -import { useState } from 'react'; import { CustomFields, Rundown, RundownSummary } from 'ontime-types'; import { millisToString } from 'ontime-utils'; +import { useState } from 'react'; import Button from '../../../../../common/components/buttons/Button'; import useRundown from '../../../../../common/hooks-query/useRundown'; import { formatDuration } from '../../../../../common/utils/time'; import * as Panel from '../../../panel-utils/PanelUtils'; - import PreviewSpreadsheet from './preview/PreviewRundown'; import useGoogleSheet from './useGoogleSheet'; import { useSheetStore } from './useSheetStore'; diff --git a/apps/client/src/features/app-settings/panel/manage-panel/sources-panel/SourcesPanel.tsx b/apps/client/src/features/app-settings/panel/manage-panel/sources-panel/SourcesPanel.tsx index 9d683b9a2..7ef60534f 100644 --- a/apps/client/src/features/app-settings/panel/manage-panel/sources-panel/SourcesPanel.tsx +++ b/apps/client/src/features/app-settings/panel/manage-panel/sources-panel/SourcesPanel.tsx @@ -1,6 +1,6 @@ +import { ImportMap, getErrorMessage } from 'ontime-utils'; import { ChangeEvent, useRef, useState } from 'react'; import { IoCloudOutline, IoDownloadOutline } from 'react-icons/io5'; -import { getErrorMessage, ImportMap } from 'ontime-utils'; import { importRundownPreview as importRundownPreviewExcel, @@ -12,10 +12,9 @@ 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'; import GSheetSetup from './GSheetSetup'; +import ImportMapForm from './import-map/ImportMapForm'; import ImportReview from './ImportReview'; import useGoogleSheet from './useGoogleSheet'; import { useSheetStore } from './useSheetStore'; diff --git a/apps/client/src/features/app-settings/panel/manage-panel/sources-panel/import-map/ImportMapForm.tsx b/apps/client/src/features/app-settings/panel/manage-panel/sources-panel/import-map/ImportMapForm.tsx index ea3ad3041..c82fbf970 100644 --- a/apps/client/src/features/app-settings/panel/manage-panel/sources-panel/import-map/ImportMapForm.tsx +++ b/apps/client/src/features/app-settings/panel/manage-panel/sources-panel/import-map/ImportMapForm.tsx @@ -1,7 +1,7 @@ +import { ImportMap, checkRegex } from 'ontime-utils'; import { useEffect, useState } from 'react'; import { useFieldArray, useForm } from 'react-hook-form'; import { IoAdd, IoTrash } from 'react-icons/io5'; -import { checkRegex, ImportMap } from 'ontime-utils'; import Button from '../../../../../../common/components/buttons/Button'; import IconButton from '../../../../../../common/components/buttons/IconButton'; @@ -12,8 +12,7 @@ import Tooltip from '../../../../../../common/components/tooltip/Tooltip'; import * as Panel from '../../../../panel-utils/PanelUtils'; import useGoogleSheet from '../useGoogleSheet'; import { useSheetStore } from '../useSheetStore'; - -import { convertToImportMap, getPersistedOptions, NamedImportMap, persistImportMap } from './importMapUtils'; +import { NamedImportMap, convertToImportMap, getPersistedOptions, persistImportMap } from './importMapUtils'; import style from '../SourcesPanel.module.scss'; diff --git a/apps/client/src/features/app-settings/panel/manage-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 index a7d38aadb..60b7ab656 100644 --- a/apps/client/src/features/app-settings/panel/manage-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 @@ -1,6 +1,6 @@ import { ImportCustom } from 'ontime-utils'; -import { convertToImportMap, NamedImportMap } from '../importMapUtils'; +import { NamedImportMap, convertToImportMap } from '../importMapUtils'; describe('convertToImportMap', () => { it('converts a namedImportMap to a importMap', () => { diff --git a/apps/client/src/features/app-settings/panel/manage-panel/sources-panel/preview/PreviewRundown.tsx b/apps/client/src/features/app-settings/panel/manage-panel/sources-panel/preview/PreviewRundown.tsx index b6a96c4fb..dbe3e04b7 100644 --- a/apps/client/src/features/app-settings/panel/manage-panel/sources-panel/preview/PreviewRundown.tsx +++ b/apps/client/src/features/app-settings/panel/manage-panel/sources-panel/preview/PreviewRundown.tsx @@ -1,7 +1,7 @@ +import { CustomFields, Rundown, isOntimeEvent, isOntimeGroup, isOntimeMilestone } from 'ontime-types'; +import { millisToString } from 'ontime-utils'; import { Fragment } from 'react'; import { IoLink } from 'react-icons/io5'; -import { CustomFields, isOntimeEvent, isOntimeGroup, isOntimeMilestone, Rundown } from 'ontime-types'; -import { millisToString } from 'ontime-utils'; import Tag from '../../../../../../common/components/tag/Tag'; import { getAccessibleColour } from '../../../../../../common/utils/styleUtils'; diff --git a/apps/client/src/features/app-settings/panel/manage-panel/sources-panel/useGoogleSheet.ts b/apps/client/src/features/app-settings/panel/manage-panel/sources-panel/useGoogleSheet.ts index 6809a251f..8cc461996 100644 --- a/apps/client/src/features/app-settings/panel/manage-panel/sources-panel/useGoogleSheet.ts +++ b/apps/client/src/features/app-settings/panel/manage-panel/sources-panel/useGoogleSheet.ts @@ -12,7 +12,6 @@ import { verifyAuthenticationStatus, } from '../../../../../common/api/sheets'; import { maybeAxiosError } from '../../../../../common/api/utils'; - import { useSheetStore } from './useSheetStore'; export default function useGoogleSheet() { diff --git a/apps/client/src/features/app-settings/panel/manage-panel/sources-panel/useSheetStore.ts b/apps/client/src/features/app-settings/panel/manage-panel/sources-panel/useSheetStore.ts index e323d4d57..bf0a28dc3 100644 --- a/apps/client/src/features/app-settings/panel/manage-panel/sources-panel/useSheetStore.ts +++ b/apps/client/src/features/app-settings/panel/manage-panel/sources-panel/useSheetStore.ts @@ -1,5 +1,5 @@ import { AuthenticationStatus, CustomFields, Rundown, RundownSummary } from 'ontime-types'; -import { defaultImportMap, ImportMap } from 'ontime-utils'; +import { ImportMap, defaultImportMap } from 'ontime-utils'; import { create } from 'zustand'; type SheetStore = { 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 6d6ed9a6f..52c648b7f 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 @@ -1,5 +1,5 @@ -import { useEffect } from 'react'; import { MessageTag } from 'ontime-types'; +import { useEffect } from 'react'; import useScrollIntoView from '../../../../common/hooks/useScrollIntoView'; import { usePing } from '../../../../common/hooks/useSocket'; @@ -7,7 +7,6 @@ import { sendSocket } from '../../../../common/utils/socket'; import { isDocker } from '../../../../externals'; import type { PanelBaseProps } from '../../panel-list/PanelList'; import * as Panel from '../../panel-utils/PanelUtils'; - import ClientControlPanel from './client-control/ClientControlPanel'; import LogExport from './NetworkLogExport'; diff --git a/apps/client/src/features/app-settings/panel/network-panel/client-control/ClientControlPanel.module.scss b/apps/client/src/features/app-settings/panel/network-panel/client-control/ClientControlPanel.module.scss index 3986b3ef6..b9a4cebf6 100644 --- a/apps/client/src/features/app-settings/panel/network-panel/client-control/ClientControlPanel.module.scss +++ b/apps/client/src/features/app-settings/panel/network-panel/client-control/ClientControlPanel.module.scss @@ -12,7 +12,7 @@ } .copiable { - cursor: text ; + cursor: text; user-select: text; } diff --git a/apps/client/src/features/app-settings/panel/network-panel/client-control/ClientControlPanel.tsx b/apps/client/src/features/app-settings/panel/network-panel/client-control/ClientControlPanel.tsx index 01d5aa15f..043d85cec 100644 --- a/apps/client/src/features/app-settings/panel/network-panel/client-control/ClientControlPanel.tsx +++ b/apps/client/src/features/app-settings/panel/network-panel/client-control/ClientControlPanel.tsx @@ -1,5 +1,4 @@ import * as Panel from '../../../panel-utils/PanelUtils'; - import ClientList from './ClientList'; export default function ClientControlPanel() { diff --git a/apps/client/src/features/app-settings/panel/network-panel/client-control/ClientList.tsx b/apps/client/src/features/app-settings/panel/network-panel/client-control/ClientList.tsx index c1698d264..70e7a5778 100644 --- a/apps/client/src/features/app-settings/panel/network-panel/client-control/ClientList.tsx +++ b/apps/client/src/features/app-settings/panel/network-panel/client-control/ClientList.tsx @@ -1,6 +1,6 @@ -import { useState } from 'react'; import { useDisclosure } from '@mantine/hooks'; import { Client } from 'ontime-types'; +import { useState } from 'react'; import Button from '../../../../../common/components/buttons/Button'; import { RedirectClientModal } from '../../../../../common/components/client-modal/RedirectClientModal'; diff --git a/apps/client/src/features/app-settings/panel/project-panel/ManageProjects.tsx b/apps/client/src/features/app-settings/panel/project-panel/ManageProjects.tsx index a8c0d8b3b..f47ef304b 100644 --- a/apps/client/src/features/app-settings/panel/project-panel/ManageProjects.tsx +++ b/apps/client/src/features/app-settings/panel/project-panel/ManageProjects.tsx @@ -7,7 +7,6 @@ import { invalidateAllCaches, maybeAxiosError } from '../../../../common/api/uti import Button from '../../../../common/components/buttons/Button'; import { validateProjectFile } from '../../../../common/utils/uploadUtils'; import * as Panel from '../../panel-utils/PanelUtils'; - import ProjectCreateForm from './ProjectCreateForm'; import ProjectList from './ProjectList'; diff --git a/apps/client/src/features/app-settings/panel/project-panel/ProjectList.tsx b/apps/client/src/features/app-settings/panel/project-panel/ProjectList.tsx index 2295f44fe..ad4feb8d6 100644 --- a/apps/client/src/features/app-settings/panel/project-panel/ProjectList.tsx +++ b/apps/client/src/features/app-settings/panel/project-panel/ProjectList.tsx @@ -4,7 +4,6 @@ import { IoArrowDown, IoArrowUp } from 'react-icons/io5'; import Info from '../../../../common/components/info/Info'; import { ProjectSortMode, useOrderedProjectList } from '../../../../common/hooks-query/useProjectList'; import * as Panel from '../../panel-utils/PanelUtils'; - import ProjectListItem, { EditMode } from './ProjectListItem'; import style from './ProjectPanel.module.scss'; diff --git a/apps/client/src/features/app-settings/panel/project-panel/ProjectListItem.tsx b/apps/client/src/features/app-settings/panel/project-panel/ProjectListItem.tsx index acc53133f..d93122e0e 100644 --- a/apps/client/src/features/app-settings/panel/project-panel/ProjectListItem.tsx +++ b/apps/client/src/features/app-settings/panel/project-panel/ProjectListItem.tsx @@ -20,7 +20,6 @@ import IconButton from '../../../../common/components/buttons/IconButton'; import { DropdownMenu } from '../../../../common/components/dropdown-menu/DropdownMenu'; import { cx } from '../../../../common/utils/styleUtils'; import * as Panel from '../../panel-utils/PanelUtils'; - import ProjectForm, { ProjectFormValues } from './ProjectForm'; import ProjectMergeForm from './ProjectMergeForm'; diff --git a/apps/client/src/features/app-settings/panel/project-panel/ProjectMergeForm.tsx b/apps/client/src/features/app-settings/panel/project-panel/ProjectMergeForm.tsx index a59274eff..f293123fa 100644 --- a/apps/client/src/features/app-settings/panel/project-panel/ProjectMergeForm.tsx +++ b/apps/client/src/features/app-settings/panel/project-panel/ProjectMergeForm.tsx @@ -1,6 +1,6 @@ +import { useQueryClient } from '@tanstack/react-query'; import { useState } from 'react'; import { useForm } from 'react-hook-form'; -import { useQueryClient } from '@tanstack/react-query'; import { PROJECT_DATA } from '../../../../common/api/constants'; import { getDb, patchData } from '../../../../common/api/db'; @@ -10,7 +10,6 @@ import Info from '../../../../common/components/info/Info'; import Switch from '../../../../common/components/switch/Switch'; import { cx } from '../../../../common/utils/styleUtils'; import * as Panel from '../../panel-utils/PanelUtils'; - import { makeProjectPatch } from './project.utils'; import style from './ProjectPanel.module.scss'; 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 9335d861a..f41a56f17 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 @@ -58,4 +58,4 @@ .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 9a2a35352..df7aba708 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 @@ -3,7 +3,6 @@ import type { PanelBaseProps } from '../../panel-list/PanelList'; import * as Panel from '../../panel-utils/PanelUtils'; import QuickStart from '../../quick-start/QuickStart'; import type { SettingsOptionId } from '../../useAppSettingsMenu'; - import ManageProjects from './ManageProjects'; interface ProjectPanelProps extends PanelBaseProps { diff --git a/apps/client/src/features/app-settings/panel/settings-panel/GeneralSettings.tsx b/apps/client/src/features/app-settings/panel/settings-panel/GeneralSettings.tsx index 428c0fad4..5478d9e0e 100644 --- a/apps/client/src/features/app-settings/panel/settings-panel/GeneralSettings.tsx +++ b/apps/client/src/features/app-settings/panel/settings-panel/GeneralSettings.tsx @@ -1,7 +1,7 @@ -import { lazy, useEffect } from 'react'; -import { useForm } from 'react-hook-form'; import { useDisclosure } from '@mantine/hooks'; import { Settings } from 'ontime-types'; +import { lazy, useEffect } from 'react'; +import { useForm } from 'react-hook-form'; import { postSettings } from '../../../../common/api/settings'; import { maybeAxiosError } from '../../../../common/api/utils'; @@ -11,7 +11,6 @@ import Select from '../../../../common/components/select/Select'; import useSettings from '../../../../common/hooks-query/useSettings'; import { preventEscape } from '../../../../common/utils/keyEvent'; import * as Panel from '../../panel-utils/PanelUtils'; - import GeneralPinInput from './composite/GeneralPinInput'; const TranslationModal = lazy(() => import('./composite/CustomTranslationModal')); diff --git a/apps/client/src/features/app-settings/panel/settings-panel/ProjectData.tsx b/apps/client/src/features/app-settings/panel/settings-panel/ProjectData.tsx index 1fafc7426..f090879f4 100644 --- a/apps/client/src/features/app-settings/panel/settings-panel/ProjectData.tsx +++ b/apps/client/src/features/app-settings/panel/settings-panel/ProjectData.tsx @@ -1,7 +1,7 @@ +import { type ProjectData } from 'ontime-types'; import { ChangeEvent, useEffect, useRef } from 'react'; import { useFieldArray, useForm } from 'react-hook-form'; import { IoAdd, IoDownloadOutline, IoTrash } from 'react-icons/io5'; -import { type ProjectData } from 'ontime-types'; import { projectLogoPath } from '../../../../common/api/constants'; import { uploadProjectLogo } from '../../../../common/api/project'; diff --git a/apps/client/src/features/app-settings/panel/settings-panel/ServerPortSettings.tsx b/apps/client/src/features/app-settings/panel/settings-panel/ServerPortSettings.tsx index f47936b03..9ba6efa0c 100644 --- a/apps/client/src/features/app-settings/panel/settings-panel/ServerPortSettings.tsx +++ b/apps/client/src/features/app-settings/panel/settings-panel/ServerPortSettings.tsx @@ -1,6 +1,6 @@ +import { PortInfo } from 'ontime-types'; import { useCallback, useEffect, useState } from 'react'; import { useForm } from 'react-hook-form'; -import { PortInfo } from 'ontime-types'; import { getServerPort, postServerPort } from '../../../../common/api/settings'; import { maybeAxiosError } from '../../../../common/api/utils'; diff --git a/apps/client/src/features/app-settings/panel/settings-panel/SettingsPanel.tsx b/apps/client/src/features/app-settings/panel/settings-panel/SettingsPanel.tsx index 8be5198f6..f96493400 100644 --- a/apps/client/src/features/app-settings/panel/settings-panel/SettingsPanel.tsx +++ b/apps/client/src/features/app-settings/panel/settings-panel/SettingsPanel.tsx @@ -2,7 +2,6 @@ import useScrollIntoView from '../../../../common/hooks/useScrollIntoView'; import { isDocker } from '../../../../externals'; import type { PanelBaseProps } from '../../panel-list/PanelList'; import * as Panel from '../../panel-utils/PanelUtils'; - import GeneralSettings from './GeneralSettings'; import ProjectData from './ProjectData'; import ServerPortSettings from './ServerPortSettings'; diff --git a/apps/client/src/features/app-settings/panel/settings-panel/ViewSettings.tsx b/apps/client/src/features/app-settings/panel/settings-panel/ViewSettings.tsx index dc60b23d5..38f641443 100644 --- a/apps/client/src/features/app-settings/panel/settings-panel/ViewSettings.tsx +++ b/apps/client/src/features/app-settings/panel/settings-panel/ViewSettings.tsx @@ -1,7 +1,7 @@ -import { useEffect } from 'react'; -import { useForm } from 'react-hook-form'; import { useDisclosure } from '@mantine/hooks'; import { ViewSettings as ViewSettingsType } from 'ontime-types'; +import { useEffect } from 'react'; +import { useForm } from 'react-hook-form'; import { maybeAxiosError } from '../../../../common/api/utils'; import Button from '../../../../common/components/buttons/Button'; @@ -12,7 +12,6 @@ import Switch from '../../../../common/components/switch/Switch'; import useViewSettings from '../../../../common/hooks-query/useViewSettings'; import { preventEscape } from '../../../../common/utils/keyEvent'; import * as Panel from '../../panel-utils/PanelUtils'; - import CodeEditorModal from './composite/StyleEditorModal'; const cssOverrideDocsUrl = 'https://docs.getontime.no/features/custom-styling/'; diff --git a/apps/client/src/features/app-settings/panel/settings-panel/composite/CustomTranslationModal.tsx b/apps/client/src/features/app-settings/panel/settings-panel/composite/CustomTranslationModal.tsx index 9808ec9a2..cd4584e43 100644 --- a/apps/client/src/features/app-settings/panel/settings-panel/composite/CustomTranslationModal.tsx +++ b/apps/client/src/features/app-settings/panel/settings-panel/composite/CustomTranslationModal.tsx @@ -1,6 +1,6 @@ +import { TranslationObject, langEn } from 'ontime-types'; import { useMemo } from 'react'; import { useForm } from 'react-hook-form'; -import { langEn, TranslationObject } from 'ontime-types'; import { maybeAxiosError } from '../../../../../common/api/utils'; import Button from '../../../../../common/components/buttons/Button'; diff --git a/apps/client/src/features/app-settings/panel/settings-panel/composite/GeneralPinInput.tsx b/apps/client/src/features/app-settings/panel/settings-panel/composite/GeneralPinInput.tsx index bbac8f071..e88e15d5c 100644 --- a/apps/client/src/features/app-settings/panel/settings-panel/composite/GeneralPinInput.tsx +++ b/apps/client/src/features/app-settings/panel/settings-panel/composite/GeneralPinInput.tsx @@ -1,7 +1,7 @@ +import { Settings } from 'ontime-types'; import { PropsWithChildren, useState } from 'react'; import { UseFormRegister } from 'react-hook-form'; import { IoEyeOutline } from 'react-icons/io5'; -import { Settings } from 'ontime-types'; import IconButton from '../../../../../common/components/buttons/IconButton'; import Input from '../../../../../common/components/input/input/Input'; diff --git a/apps/client/src/features/app-settings/panel/settings-panel/composite/StyleEditor.tsx b/apps/client/src/features/app-settings/panel/settings-panel/composite/StyleEditor.tsx index ad14ae471..53789bbc6 100644 --- a/apps/client/src/features/app-settings/panel/settings-panel/composite/StyleEditor.tsx +++ b/apps/client/src/features/app-settings/panel/settings-panel/composite/StyleEditor.tsx @@ -1,7 +1,6 @@ +import Prism from 'prismjs/components/prism-core'; import { forwardRef, memo, useEffect, useImperativeHandle, useState } from 'react'; import Editor from 'react-simple-code-editor'; -import Prism from 'prismjs/components/prism-core'; - import 'prismjs/components/prism-css'; import 'prismjs/themes/prism-tomorrow.min.css'; import style from './StyleEditor.module.scss'; diff --git a/apps/client/src/features/app-settings/panel/settings-panel/composite/StyleEditorModal.module.scss b/apps/client/src/features/app-settings/panel/settings-panel/composite/StyleEditorModal.module.scss index 37112ff57..084608cc4 100644 --- a/apps/client/src/features/app-settings/panel/settings-panel/composite/StyleEditorModal.module.scss +++ b/apps/client/src/features/app-settings/panel/settings-panel/composite/StyleEditorModal.module.scss @@ -4,7 +4,7 @@ .right { align-self: end; - text-align: right + text-align: right; } .column { diff --git a/apps/client/src/features/app-settings/panel/settings-panel/composite/StyleEditorModal.tsx b/apps/client/src/features/app-settings/panel/settings-panel/composite/StyleEditorModal.tsx index 0a70061d1..c91c5c20b 100644 --- a/apps/client/src/features/app-settings/panel/settings-panel/composite/StyleEditorModal.tsx +++ b/apps/client/src/features/app-settings/panel/settings-panel/composite/StyleEditorModal.tsx @@ -1,4 +1,4 @@ -import { lazy, Suspense, useEffect, useRef, useState } from 'react'; +import { Suspense, lazy, useEffect, useRef, useState } from 'react'; import { getCSSContents, postCSSContents, restoreCSSContents } from '../../../../../common/api/assets'; import Button from '../../../../../common/components/buttons/Button'; 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 b491a611c..a04ef0f5a 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,5 +1,5 @@ -import { useRef } from 'react'; import { useDisclosure } from '@mantine/hooks'; +import { useRef } from 'react'; import Button from '../../../../common/components/buttons/Button'; import Dialog from '../../../../common/components/dialog/Dialog'; diff --git a/apps/client/src/features/app-settings/quick-start/QuickStart.tsx b/apps/client/src/features/app-settings/quick-start/QuickStart.tsx index 147791eb6..991fbf748 100644 --- a/apps/client/src/features/app-settings/quick-start/QuickStart.tsx +++ b/apps/client/src/features/app-settings/quick-start/QuickStart.tsx @@ -1,6 +1,6 @@ -import { useForm } from 'react-hook-form'; import { QuickStartData } from 'ontime-types'; import { parseUserTime } from 'ontime-utils'; +import { useForm } from 'react-hook-form'; import { quickProject } from '../../../common/api/db'; import { invalidateAllCaches, maybeAxiosError } from '../../../common/api/utils'; @@ -11,7 +11,6 @@ import Modal from '../../../common/components/modal/Modal'; import Select from '../../../common/components/select/Select'; import { editorSettingsDefaults, useEditorSettings } from '../../../common/stores/editorSettings'; import * as Panel from '../panel-utils/PanelUtils'; - import { quickStartDefaults } from './quickStart.utils'; interface QuickStartProps { diff --git a/apps/client/src/features/control/message/MessageControl.tsx b/apps/client/src/features/control/message/MessageControl.tsx index b53311910..54270651f 100644 --- a/apps/client/src/features/control/message/MessageControl.tsx +++ b/apps/client/src/features/control/message/MessageControl.tsx @@ -6,7 +6,6 @@ import { useExternalMessageInput as useSecondaryMessageInput, useTimerMessageInput, } from '../../../common/hooks/useSocket'; - import InputRow from './InputRow'; import TimerControlsPreview from './TimerViewControl'; diff --git a/apps/client/src/features/control/message/MessageControlExport.tsx b/apps/client/src/features/control/message/MessageControlExport.tsx index e49992730..2a54d2bc8 100644 --- a/apps/client/src/features/control/message/MessageControlExport.tsx +++ b/apps/client/src/features/control/message/MessageControlExport.tsx @@ -6,7 +6,6 @@ import ViewNavigationMenu from '../../../common/components/navigation-menu/ViewN import ProtectRoute from '../../../common/components/protect-route/ProtectRoute'; import { handleLinks } from '../../../common/utils/linkUtils'; import { getIsNavigationLocked } from '../../../externals'; - import MessageControl from './MessageControl'; import style from './MessageControlExport.module.scss'; diff --git a/apps/client/src/features/control/message/TimerPreview.module.scss b/apps/client/src/features/control/message/TimerPreview.module.scss index 0325ee4e7..7f64c4856 100644 --- a/apps/client/src/features/control/message/TimerPreview.module.scss +++ b/apps/client/src/features/control/message/TimerPreview.module.scss @@ -47,4 +47,3 @@ color: $active-indicator; } } - diff --git a/apps/client/src/features/control/message/TimerPreview.tsx b/apps/client/src/features/control/message/TimerPreview.tsx index 3d0d0ae92..62c7e6709 100644 --- a/apps/client/src/features/control/message/TimerPreview.tsx +++ b/apps/client/src/features/control/message/TimerPreview.tsx @@ -1,11 +1,11 @@ +import { TimerPhase, TimerType } from 'ontime-types'; import { IoArrowDown, IoArrowUp, IoBan, IoTime } from 'react-icons/io5'; import { LuArrowDownToLine } from 'react-icons/lu'; -import { TimerPhase, TimerType } from 'ontime-types'; import { CornerWithPip } from '../../../common/components/editor-utils/EditorUtils'; import Tooltip from '../../../common/components/tooltip/Tooltip'; -import { useMessagePreview } from '../../../common/hooks/useSocket'; import useViewSettings from '../../../common/hooks-query/useViewSettings'; +import { useMessagePreview } from '../../../common/hooks/useSocket'; import { handleLinks } from '../../../common/utils/linkUtils'; import { cx, timerPlaceholder } from '../../../common/utils/styleUtils'; import PipRoot from '../../../views/editor/pip-timer/PipRoot'; diff --git a/apps/client/src/features/control/message/TimerViewControl.module.scss b/apps/client/src/features/control/message/TimerViewControl.module.scss index c877a71bb..df7d97c4f 100644 --- a/apps/client/src/features/control/message/TimerViewControl.module.scss +++ b/apps/client/src/features/control/message/TimerViewControl.module.scss @@ -4,9 +4,8 @@ grid-template-columns: 3fr 2fr; } - .options { display: flex; flex-direction: column; gap: $element-spacing; -} \ No newline at end of file +} diff --git a/apps/client/src/features/control/message/TimerViewControl.tsx b/apps/client/src/features/control/message/TimerViewControl.tsx index 82b2542c6..a561d47b4 100644 --- a/apps/client/src/features/control/message/TimerViewControl.tsx +++ b/apps/client/src/features/control/message/TimerViewControl.tsx @@ -1,11 +1,10 @@ -import { useEffect, useState } from 'react'; import { SecondarySource } from 'ontime-types'; +import { useEffect, useState } from 'react'; import Button from '../../../common/components/buttons/Button'; import * as Editor from '../../../common/components/editor-utils/EditorUtils'; import Select from '../../../common/components/select/Select'; import { setMessage, useTimerViewControl } from '../../../common/hooks/useSocket'; - import TimerPreview from './TimerPreview'; import style from './TimerViewControl.module.scss'; diff --git a/apps/client/src/features/control/playback/PlaybackControl.tsx b/apps/client/src/features/control/playback/PlaybackControl.tsx index 3476ef3a7..71cbb42be 100644 --- a/apps/client/src/features/control/playback/PlaybackControl.tsx +++ b/apps/client/src/features/control/playback/PlaybackControl.tsx @@ -1,5 +1,4 @@ import { usePlaybackControl } from '../../../common/hooks/useSocket'; - import AddTime from './add-time/AddTime'; import { AuxTimer } from './aux-timer/AuxTimer'; import PlaybackButtons from './playback-buttons/PlaybackButtons'; diff --git a/apps/client/src/features/control/playback/TimerControlExport.tsx b/apps/client/src/features/control/playback/TimerControlExport.tsx index 6854111be..390714a2a 100644 --- a/apps/client/src/features/control/playback/TimerControlExport.tsx +++ b/apps/client/src/features/control/playback/TimerControlExport.tsx @@ -6,7 +6,6 @@ import ViewNavigationMenu from '../../../common/components/navigation-menu/ViewN import ProtectRoute from '../../../common/components/protect-route/ProtectRoute'; import { handleLinks } from '../../../common/utils/linkUtils'; import { getIsNavigationLocked } from '../../../externals'; - import PlaybackControl from './PlaybackControl'; import style from './TimerControlExport.module.scss'; diff --git a/apps/client/src/features/control/playback/add-time/AddTime.tsx b/apps/client/src/features/control/playback/add-time/AddTime.tsx index b53566611..6c580e75b 100644 --- a/apps/client/src/features/control/playback/add-time/AddTime.tsx +++ b/apps/client/src/features/control/playback/add-time/AddTime.tsx @@ -1,7 +1,7 @@ -import { IoAdd, IoRemove } from 'react-icons/io5'; import { useLocalStorage } from '@mantine/hooks'; import { Playback } from 'ontime-types'; import { MILLIS_PER_HOUR, parseUserTime } from 'ontime-utils'; +import { IoAdd, IoRemove } from 'react-icons/io5'; import TimeInput from '../../../../common/components/input/time-input/TimeInput'; import { setPlayback } from '../../../../common/hooks/useSocket'; diff --git a/apps/client/src/features/control/playback/aux-timer/AuxTimer.tsx b/apps/client/src/features/control/playback/aux-timer/AuxTimer.tsx index fdb3ab61f..3dff8eab5 100644 --- a/apps/client/src/features/control/playback/aux-timer/AuxTimer.tsx +++ b/apps/client/src/features/control/playback/aux-timer/AuxTimer.tsx @@ -1,6 +1,6 @@ -import { IoArrowDown, IoArrowUp, IoPause, IoPlay, IoStop } from 'react-icons/io5'; import { Playback, SimpleDirection, SimplePlayback } from 'ontime-types'; import { millisToString, parseUserTime } from 'ontime-utils'; +import { IoArrowDown, IoArrowUp, IoPause, IoPlay, IoStop } from 'react-icons/io5'; import TimeInput from '../../../../common/components/input/time-input/TimeInput'; import { setAuxTimer, useAuxTimerControl, useAuxTimerTime } from '../../../../common/hooks/useSocket'; diff --git a/apps/client/src/features/control/playback/playback-buttons/PlaybackButtons.module.scss b/apps/client/src/features/control/playback/playback-buttons/PlaybackButtons.module.scss index 2cf4d1456..77577eb71 100644 --- a/apps/client/src/features/control/playback/playback-buttons/PlaybackButtons.module.scss +++ b/apps/client/src/features/control/playback/playback-buttons/PlaybackButtons.module.scss @@ -2,9 +2,9 @@ padding-top: $element-spacing; display: grid; grid-template-areas: - "go playback" - "go transport" - "extra extra"; + 'go playback' + 'go transport' + 'extra extra'; grid-template-rows: repeat(3, 2rem); gap: $element-spacing; } @@ -38,4 +38,3 @@ .invertX { transform: rotateY(180deg); } - diff --git a/apps/client/src/features/control/playback/playback-buttons/PlaybackButtons.tsx b/apps/client/src/features/control/playback/playback-buttons/PlaybackButtons.tsx index 515e13238..bca5109b8 100644 --- a/apps/client/src/features/control/playback/playback-buttons/PlaybackButtons.tsx +++ b/apps/client/src/features/control/playback/playback-buttons/PlaybackButtons.tsx @@ -1,5 +1,5 @@ -import { IoPause, IoPlay, IoPlaySkipBack, IoPlaySkipForward, IoReload, IoStop } from 'react-icons/io5'; import { Playback, TimerPhase } from 'ontime-types'; +import { IoPause, IoPlay, IoPlaySkipBack, IoPlaySkipForward, IoReload, IoStop } from 'react-icons/io5'; import { setPlayback } from '../../../../common/hooks/useSocket'; import { getPlaybackControlState } from '../playbackControl.utils'; diff --git a/apps/client/src/features/control/playback/playback-timer/PlaybackTimer.tsx b/apps/client/src/features/control/playback/playback-timer/PlaybackTimer.tsx index 24cfcda66..ec4672e61 100644 --- a/apps/client/src/features/control/playback/playback-timer/PlaybackTimer.tsx +++ b/apps/client/src/features/control/playback/playback-timer/PlaybackTimer.tsx @@ -1,11 +1,11 @@ -import { PropsWithChildren } from 'react'; import { MaybeNumber, Playback, TimerPhase } from 'ontime-types'; import { dayInMs, millisToString } from 'ontime-utils'; +import { PropsWithChildren } from 'react'; import AppLink from '../../../../common/components/link/app-link/AppLink'; import Tooltip from '../../../../common/components/tooltip/Tooltip'; -import { useTimer } from '../../../../common/hooks/useSocket'; import useReport from '../../../../common/hooks-query/useReport'; +import { useTimer } from '../../../../common/hooks/useSocket'; import { formatDuration } from '../../../../common/utils/time'; import TimerDisplay from '../timer-display/TimerDisplay'; diff --git a/apps/client/src/features/control/playback/tap-button/TapButton.tsx b/apps/client/src/features/control/playback/tap-button/TapButton.tsx index bec58fc37..c45b6d750 100644 --- a/apps/client/src/features/control/playback/tap-button/TapButton.tsx +++ b/apps/client/src/features/control/playback/tap-button/TapButton.tsx @@ -1,5 +1,5 @@ -import { ForwardedRef, forwardRef, PropsWithChildren } from 'react'; import { Playback } from 'ontime-types'; +import { ForwardedRef, PropsWithChildren, forwardRef } from 'react'; import { cx } from '../../../../common/utils/styleUtils'; diff --git a/apps/client/src/features/control/playback/tracking-playback-bar/TrackingPlaybackBar.tsx b/apps/client/src/features/control/playback/tracking-playback-bar/TrackingPlaybackBar.tsx index 859c5478d..f5f88b91f 100644 --- a/apps/client/src/features/control/playback/tracking-playback-bar/TrackingPlaybackBar.tsx +++ b/apps/client/src/features/control/playback/tracking-playback-bar/TrackingPlaybackBar.tsx @@ -1,7 +1,7 @@ -import { IoAdd, IoArrowDown, IoArrowUp, IoPause, IoPlay, IoPlaySkipForward, IoRemove, IoStop } from 'react-icons/io5'; import { useHotkeys, useLocalStorage } from '@mantine/hooks'; import { Playback, SimpleDirection, SimplePlayback, TimerPhase } from 'ontime-types'; import { millisToString, parseUserTime } from 'ontime-utils'; +import { IoAdd, IoArrowDown, IoArrowUp, IoPause, IoPlay, IoPlaySkipForward, IoRemove, IoStop } from 'react-icons/io5'; import TimeInput from '../../../../common/components/input/time-input/TimeInput'; import { diff --git a/apps/client/src/features/log/Log.tsx b/apps/client/src/features/log/Log.tsx index 158fa30ca..ae158eb47 100644 --- a/apps/client/src/features/log/Log.tsx +++ b/apps/client/src/features/log/Log.tsx @@ -1,6 +1,6 @@ +import { LogOrigin } from 'ontime-types'; import { useCallback, useState } from 'react'; import { IoClose } from 'react-icons/io5'; -import { LogOrigin } from 'ontime-types'; import Button from '../../common/components/buttons/Button'; import { clearLogs, useLogData } from '../../common/stores/logger'; @@ -41,12 +41,12 @@ export default function Log() { const filteredData = logData.filter((entry) => matchers.some((match) => entry.origin === match)); const disableOthers = useCallback((toEnable: LogOrigin) => { - toEnable === LogOrigin.User ? setShowUser(true) : setShowUser(false); - toEnable === LogOrigin.Client ? setShowClient(true) : setShowClient(false); - toEnable === LogOrigin.Server ? setShowServer(true) : setShowServer(false); - toEnable === LogOrigin.Rx ? setShowRx(true) : setShowRx(false); - toEnable === LogOrigin.Tx ? setShowTx(true) : setShowTx(false); - toEnable === LogOrigin.Playback ? setShowPlayback(true) : setShowPlayback(false); + setShowUser(toEnable === LogOrigin.User); + setShowClient(toEnable === LogOrigin.Client); + setShowServer(toEnable === LogOrigin.Server); + setShowRx(toEnable === LogOrigin.Rx); + setShowTx(toEnable === LogOrigin.Tx); + setShowPlayback(toEnable === LogOrigin.Playback); }, []); return ( diff --git a/apps/client/src/features/operator/Operator.tsx b/apps/client/src/features/operator/Operator.tsx index a9ccfa459..e594faccc 100644 --- a/apps/client/src/features/operator/Operator.tsx +++ b/apps/client/src/features/operator/Operator.tsx @@ -1,5 +1,5 @@ +import { OntimeView, isOntimeEvent, isOntimeGroup } from 'ontime-types'; import { Fragment, useCallback, useEffect, useMemo, useRef, useState } from 'react'; -import { isOntimeEvent, isOntimeGroup, OntimeView } from 'ontime-types'; import EmptyPage from '../../common/components/state/EmptyPage'; import ViewParamsEditor from '../../common/components/view-params-editor/ViewParamsEditor'; @@ -11,15 +11,14 @@ import { throttle } from '../../common/utils/throttle'; import { getDefaultFormat } from '../../common/utils/time'; import { isTouchDevice } from '../../externals'; import Loader from '../../views/common/loader/Loader'; - import CustomFieldEditModal from './custom-field-edit-modal/CustomFieldEditModal'; import FollowButton from './follow-button/FollowButton'; import OperatorEvent from './operator-event/OperatorEvent'; import OperatorGroup from './operator-group/OperatorGroup'; -import StatusBar from './status-bar/StatusBar'; import { getOperatorOptions, useOperatorOptions } from './operator.options'; import type { EditEvent } from './operator.types'; import { getEventData } from './operator.utils'; +import StatusBar from './status-bar/StatusBar'; import { OperatorData, useOperatorData } from './useOperatorData'; import style from './Operator.module.scss'; diff --git a/apps/client/src/features/operator/OperatorExport.tsx b/apps/client/src/features/operator/OperatorExport.tsx index cfd8fda88..f29f65b38 100644 --- a/apps/client/src/features/operator/OperatorExport.tsx +++ b/apps/client/src/features/operator/OperatorExport.tsx @@ -1,5 +1,4 @@ import ProtectRoute from '../../common/components/protect-route/ProtectRoute'; - import Operator from './Operator'; export default function OperatorExport() { diff --git a/apps/client/src/features/operator/custom-field-edit-modal/CustomFieldEditModal.module.scss b/apps/client/src/features/operator/custom-field-edit-modal/CustomFieldEditModal.module.scss index fc2b49f90..346fe37a9 100644 --- a/apps/client/src/features/operator/custom-field-edit-modal/CustomFieldEditModal.module.scss +++ b/apps/client/src/features/operator/custom-field-edit-modal/CustomFieldEditModal.module.scss @@ -7,7 +7,7 @@ padding-inline: 1rem; min-width: min(720px, 90vw); - + background-color: $gray-1250; color: $ui-white; border-radius: 3px; diff --git a/apps/client/src/features/operator/custom-field-edit-modal/CustomFieldEditModal.tsx b/apps/client/src/features/operator/custom-field-edit-modal/CustomFieldEditModal.tsx index 3fc7c2ce4..f7b39874d 100644 --- a/apps/client/src/features/operator/custom-field-edit-modal/CustomFieldEditModal.tsx +++ b/apps/client/src/features/operator/custom-field-edit-modal/CustomFieldEditModal.tsx @@ -1,7 +1,7 @@ -import { Fragment, useRef, useState } from 'react'; -import { IoClose } from 'react-icons/io5'; import { Dialog } from '@base-ui/react/dialog'; import { OntimeEvent } from 'ontime-types'; +import { Fragment, useRef, useState } from 'react'; +import { IoClose } from 'react-icons/io5'; import Button from '../../../common/components/buttons/Button'; import IconButton from '../../../common/components/buttons/IconButton'; diff --git a/apps/client/src/features/operator/follow-button/FollowButton.module.scss b/apps/client/src/features/operator/follow-button/FollowButton.module.scss index 4736d02ae..e33f584aa 100644 --- a/apps/client/src/features/operator/follow-button/FollowButton.module.scss +++ b/apps/client/src/features/operator/follow-button/FollowButton.module.scss @@ -35,4 +35,4 @@ gap: 1rem; padding: 0.25rem 1rem; } -} \ No newline at end of file +} diff --git a/apps/client/src/features/operator/operator-event/OperatorEvent.tsx b/apps/client/src/features/operator/operator-event/OperatorEvent.tsx index 69eb2e3fb..a081bd04a 100644 --- a/apps/client/src/features/operator/operator-event/OperatorEvent.tsx +++ b/apps/client/src/features/operator/operator-event/OperatorEvent.tsx @@ -1,6 +1,6 @@ -import { CSSProperties, memo, RefObject, SyntheticEvent } from 'react'; import { Day } from 'ontime-types'; import { MILLIS_PER_MINUTE, MILLIS_PER_SECOND } from 'ontime-utils'; +import { CSSProperties, RefObject, SyntheticEvent, memo } from 'react'; import DelayIndicator from '../../../common/components/delay-indicator/DelayIndicator'; import { useLongPress } from '../../../common/hooks/useLongPress'; diff --git a/apps/client/src/features/operator/operator.options.tsx b/apps/client/src/features/operator/operator.options.tsx index cfd49e4c5..9dd38ac06 100644 --- a/apps/client/src/features/operator/operator.options.tsx +++ b/apps/client/src/features/operator/operator.options.tsx @@ -1,6 +1,6 @@ +import { CustomFields, EntryId, OntimeEvent } from 'ontime-types'; import { use, useMemo } from 'react'; import { useSearchParams } from 'react-router'; -import { CustomFields, EntryId, OntimeEvent } from 'ontime-types'; import { getTimeOption } from '../../common/components/view-params-editor/common.options'; import { OptionTitle } from '../../common/components/view-params-editor/constants'; diff --git a/apps/client/src/features/operator/operator.utils.ts b/apps/client/src/features/operator/operator.utils.ts index e0b5c8103..51ca3e0a6 100644 --- a/apps/client/src/features/operator/operator.utils.ts +++ b/apps/client/src/features/operator/operator.utils.ts @@ -1,33 +1,32 @@ -import { CustomFields, MaybeString, OntimeEvent } from 'ontime-types'; - -import { getPropertyValue } from '../../views/common/viewUtils'; - -import type { Subscribed } from './operator.types'; - -export function getEventData( - event: OntimeEvent, - main: MaybeString, - secondary: MaybeString, - subscriptions: string[], - customFields: CustomFields, -) { - const mainField = main ? getPropertyValue(event, main) ?? '' : event.title; - const secondaryField = getPropertyValue(event, secondary) ?? ''; - - // remove subscriptions that are not in customFields - const sanitisedSubscriptions = subscriptions.filter((field) => Object.hasOwn(customFields, field)); - const subscribedData = sanitisedSubscriptions.reduce((acc, id) => { - const field = customFields[id]; - if (field) { - acc.push({ - id, - label: field.label, - colour: field.colour, - value: event.custom[id], - }); - } - return acc; - }, []); - - return { mainField, secondaryField, subscribedData }; -} +import { CustomFields, MaybeString, OntimeEvent } from 'ontime-types'; + +import { getPropertyValue } from '../../views/common/viewUtils'; +import type { Subscribed } from './operator.types'; + +export function getEventData( + event: OntimeEvent, + main: MaybeString, + secondary: MaybeString, + subscriptions: string[], + customFields: CustomFields, +) { + const mainField = main ? (getPropertyValue(event, main) ?? '') : event.title; + const secondaryField = getPropertyValue(event, secondary) ?? ''; + + // remove subscriptions that are not in customFields + const sanitisedSubscriptions = subscriptions.filter((field) => Object.hasOwn(customFields, field)); + const subscribedData = sanitisedSubscriptions.reduce((acc, id) => { + const field = customFields[id]; + if (field) { + acc.push({ + id, + label: field.label, + colour: field.colour, + value: event.custom[id], + }); + } + return acc; + }, []); + + return { mainField, secondaryField, subscribedData }; +} diff --git a/apps/client/src/features/operator/status-bar/StatusBar.tsx b/apps/client/src/features/operator/status-bar/StatusBar.tsx index c6f09e65c..a940fb421 100644 --- a/apps/client/src/features/operator/status-bar/StatusBar.tsx +++ b/apps/client/src/features/operator/status-bar/StatusBar.tsx @@ -1,5 +1,4 @@ import useViewSettings from '../../../common/hooks-query/useViewSettings'; - import StatusBarProgress from './StatusBarProgress'; import StatusBarTimers from './StatusBarTimers'; diff --git a/apps/client/src/features/operator/useOperatorData.ts b/apps/client/src/features/operator/useOperatorData.ts index 0164d4be3..8eeeae6b2 100644 --- a/apps/client/src/features/operator/useOperatorData.ts +++ b/apps/client/src/features/operator/useOperatorData.ts @@ -4,7 +4,7 @@ import useCustomFields from '../../common/hooks-query/useCustomFields'; import { useRundownWithMetadata } from '../../common/hooks-query/useRundown'; import useSettings from '../../common/hooks-query/useSettings'; import { RundownMetadataObject } from '../../common/utils/rundownMetadata'; -import { aggregateQueryStatus, ViewData } from '../../views/utils/viewLoader.utils'; +import { ViewData, aggregateQueryStatus } from '../../views/utils/viewLoader.utils'; export interface OperatorData { rundown: Rundown; diff --git a/apps/client/src/features/overview/CuesheetOverview.tsx b/apps/client/src/features/overview/CuesheetOverview.tsx index 1ea5d8bc3..2fea09245 100644 --- a/apps/client/src/features/overview/CuesheetOverview.tsx +++ b/apps/client/src/features/overview/CuesheetOverview.tsx @@ -1,7 +1,6 @@ -import { memo, PropsWithChildren } from 'react'; +import { PropsWithChildren, memo } from 'react'; import { useIsMobileScreen } from '../../common/hooks/useIsMobileScreen'; - import { ClockOverview, MetadataTimes, diff --git a/apps/client/src/features/overview/EditorOverview.tsx b/apps/client/src/features/overview/EditorOverview.tsx index 76b64c2a7..70e53662d 100644 --- a/apps/client/src/features/overview/EditorOverview.tsx +++ b/apps/client/src/features/overview/EditorOverview.tsx @@ -1,7 +1,6 @@ -import { memo, PropsWithChildren } from 'react'; +import { PropsWithChildren, memo } from 'react'; import { EditorLayoutMode, useEditorLayout } from '../../views/editor/useEditorLayout'; - import { ClockOverview, MetadataTimes, diff --git a/apps/client/src/features/overview/OverviewWrapper.tsx b/apps/client/src/features/overview/OverviewWrapper.tsx index aeb13ff21..b0afa1d4c 100644 --- a/apps/client/src/features/overview/OverviewWrapper.tsx +++ b/apps/client/src/features/overview/OverviewWrapper.tsx @@ -1,5 +1,5 @@ -import { PropsWithChildren, ReactNode } from 'react'; import { ErrorBoundary } from '@sentry/react'; +import { PropsWithChildren, ReactNode } from 'react'; import ScrollArea from '../../common/components/scroll-area/ScrollArea'; import { useIsOnline } from '../../common/hooks/useSocket'; diff --git a/apps/client/src/features/overview/composite/TimeElements.module.scss b/apps/client/src/features/overview/composite/TimeElements.module.scss index 3eca4e050..5d3af7dfb 100644 --- a/apps/client/src/features/overview/composite/TimeElements.module.scss +++ b/apps/client/src/features/overview/composite/TimeElements.module.scss @@ -57,9 +57,9 @@ display: inline-flex; align-items: center; margin-left: 0.25rem; - + &::after { - content: "+" attr(data-day-offset); + content: '+' attr(data-day-offset); font-size: 0.75rem; font-weight: 400; color: $ui-white; diff --git a/apps/client/src/features/overview/composite/TimeElements.tsx b/apps/client/src/features/overview/composite/TimeElements.tsx index aaa6e5b69..c51156f77 100644 --- a/apps/client/src/features/overview/composite/TimeElements.tsx +++ b/apps/client/src/features/overview/composite/TimeElements.tsx @@ -1,3 +1,5 @@ +import { OffsetMode, OntimeEvent, OntimeGroup, TimerPhase, TimerType } from 'ontime-types'; +import { dayInMs, isPlaybackActive, millisToString } from 'ontime-utils'; import { useMemo } from 'react'; import { TbCalendarClock, @@ -8,10 +10,9 @@ import { TbFolderPin, TbFolderStar, } from 'react-icons/tb'; -import { OffsetMode, OntimeEvent, OntimeGroup, TimerPhase, TimerType } from 'ontime-types'; -import { dayInMs, isPlaybackActive, millisToString } from 'ontime-utils'; import Tooltip from '../../../common/components/tooltip/Tooltip'; +import { useEntry } from '../../../common/hooks-query/useRundown'; import { useClock, useCurrentGroupId, @@ -24,13 +25,11 @@ import { useStartTimesOverview, useTimer, } from '../../../common/hooks/useSocket'; -import { useEntry } from '../../../common/hooks-query/useRundown'; import { getOffsetState, getOffsetText } from '../../../common/utils/offset'; import { cx, enDash, timerPlaceholder } from '../../../common/utils/styleUtils'; import { formatDuration, formatTime } from '../../../common/utils/time'; import SuperscriptPeriod from '../../../views/common/superscript-time/SuperscriptPeriod'; import { calculateEndAndDaySpan, formatDueTime } from '../overview.utils'; - import { OverUnder, TimeColumn, WrappedInTimeColumn } from './TimeLayout'; import style from './TimeElements.module.scss'; diff --git a/apps/client/src/features/rundown/Rundown.module.scss b/apps/client/src/features/rundown/Rundown.module.scss index 87aa05ff2..f0a1d30aa 100644 --- a/apps/client/src/features/rundown/Rundown.module.scss +++ b/apps/client/src/features/rundown/Rundown.module.scss @@ -46,7 +46,7 @@ .entryIndex { padding-block: 0.25rem; display: grid; - grid-template-rows: 1fr 1fr 1fr; + grid-template-rows: 1fr 1fr 1fr; justify-items: end; min-width: 2em; color: $label-gray; diff --git a/apps/client/src/features/rundown/Rundown.tsx b/apps/client/src/features/rundown/Rundown.tsx index 892c7262f..1118652a0 100644 --- a/apps/client/src/features/rundown/Rundown.tsx +++ b/apps/client/src/features/rundown/Rundown.tsx @@ -1,22 +1,21 @@ -import { type HTMLProps, forwardRef, Fragment, useCallback, useEffect, useMemo, useRef, useState } from 'react'; -import { TbFlagFilled } from 'react-icons/tb'; -import { Virtuoso, VirtuosoHandle } from 'react-virtuoso'; -import { closestCenter, DndContext } from '@dnd-kit/core'; +import { DndContext, closestCenter } from '@dnd-kit/core'; import { SortableContext, verticalListSortingStrategy } from '@dnd-kit/sortable'; import { type EntryId, + Playback, type Rundown as RundownType, + SupportedEntry, isOntimeEvent, isOntimeGroup, - Playback, - SupportedEntry, } from 'ontime-types'; +import { Fragment, type HTMLProps, forwardRef, useCallback, useEffect, useMemo, useRef, useState } from 'react'; +import { TbFlagFilled } from 'react-icons/tb'; +import { Virtuoso, VirtuosoHandle } from 'react-virtuoso'; import { useEntryActionsContext } from '../../common/context/EntryActionsContext'; import { useEntryCopy } from '../../common/stores/entryCopyStore'; -import { lastMetadataKey, RundownMetadataObject } from '../../common/utils/rundownMetadata'; +import { RundownMetadataObject, lastMetadataKey } from '../../common/utils/rundownMetadata'; import { AppMode } from '../../ontimeConfig'; - import QuickAddButtons from './entry-editor/quick-add-buttons/QuickAddButtons'; import QuickAddInline from './entry-editor/quick-add-cursor/QuickAddInline'; import { useRundownCommands } from './hooks/useRundownCommands'; diff --git a/apps/client/src/features/rundown/RundownEmpty.tsx b/apps/client/src/features/rundown/RundownEmpty.tsx index 5718c1193..bb321850e 100644 --- a/apps/client/src/features/rundown/RundownEmpty.tsx +++ b/apps/client/src/features/rundown/RundownEmpty.tsx @@ -1,5 +1,5 @@ -import { IoAdd } from 'react-icons/io5'; import { SupportedEntry } from 'ontime-types'; +import { IoAdd } from 'react-icons/io5'; import Button from '../../common/components/buttons/Button'; import * as Editor from '../../common/components/editor-utils/EditorUtils'; diff --git a/apps/client/src/features/rundown/RundownEntry.tsx b/apps/client/src/features/rundown/RundownEntry.tsx index 7a180a302..0f7084f87 100644 --- a/apps/client/src/features/rundown/RundownEntry.tsx +++ b/apps/client/src/features/rundown/RundownEntry.tsx @@ -1,4 +1,4 @@ -import { isOntimeDelay, isOntimeEvent, isOntimeMilestone, OntimeEntry, Playback, SupportedEntry } from 'ontime-types'; +import { OntimeEntry, Playback, SupportedEntry, isOntimeDelay, isOntimeEvent, isOntimeMilestone } from 'ontime-types'; import RundownDelay from './rundown-delay/RundownDelay'; import RundownEvent from './rundown-event/RundownEvent'; diff --git a/apps/client/src/features/rundown/RundownExport.tsx b/apps/client/src/features/rundown/RundownExport.tsx index dd389a2c7..55cc2c1d3 100644 --- a/apps/client/src/features/rundown/RundownExport.tsx +++ b/apps/client/src/features/rundown/RundownExport.tsx @@ -1,5 +1,5 @@ -import { memo } from 'react'; import { useSessionStorage } from '@mantine/hooks'; +import { memo } from 'react'; import * as Editor from '../../common/components/editor-utils/EditorUtils'; import ErrorBoundary from '../../common/components/error-boundary/ErrorBoundary'; @@ -14,7 +14,6 @@ import { getIsNavigationLocked } from '../../externals'; import { AppMode } from '../../ontimeConfig'; import EntryEditModal from '../../views/cuesheet/cuesheet-edit-modal/EntryEditModal'; import { EditorLayoutMode, useEditorLayout } from '../../views/editor/useEditorLayout'; - import RundownEntryEditor from './entry-editor/RundownEntryEditor'; import FinderPlacement from './placements/FinderPlacement'; import { RundownContextMenu } from './rundown-context-menu/RundownContextMenu'; diff --git a/apps/client/src/features/rundown/RundownList.tsx b/apps/client/src/features/rundown/RundownList.tsx index 94673400a..5718a8ea1 100644 --- a/apps/client/src/features/rundown/RundownList.tsx +++ b/apps/client/src/features/rundown/RundownList.tsx @@ -1,9 +1,8 @@ import { memo } from 'react'; import Empty from '../../common/components/state/Empty'; -import { useRundownEditor } from '../../common/hooks/useSocket'; import { useRundownWithMetadata } from '../../common/hooks-query/useRundown'; - +import { useRundownEditor } from '../../common/hooks/useSocket'; import Rundown from './Rundown'; export default memo(RundownList); diff --git a/apps/client/src/features/rundown/entry-editor/CuesheetEventEditor.tsx b/apps/client/src/features/rundown/entry-editor/CuesheetEventEditor.tsx index 587bf7886..b9f8896a2 100644 --- a/apps/client/src/features/rundown/entry-editor/CuesheetEventEditor.tsx +++ b/apps/client/src/features/rundown/entry-editor/CuesheetEventEditor.tsx @@ -1,8 +1,7 @@ +import { OntimeEntry, isOntimeEvent, isOntimeGroup, isOntimeMilestone } from 'ontime-types'; import { useMemo } from 'react'; -import { isOntimeEvent, isOntimeGroup, isOntimeMilestone, OntimeEntry } from 'ontime-types'; import useRundown from '../../../common/hooks-query/useRundown'; - import EventEditor from './EventEditor'; import GroupEditor from './GroupEditor'; import MilestoneEditor from './MilestoneEditor'; diff --git a/apps/client/src/features/rundown/entry-editor/EventEditor.tsx b/apps/client/src/features/rundown/entry-editor/EventEditor.tsx index 0e544b55c..b41773a28 100644 --- a/apps/client/src/features/rundown/entry-editor/EventEditor.tsx +++ b/apps/client/src/features/rundown/entry-editor/EventEditor.tsx @@ -1,11 +1,10 @@ -import { useCallback } from 'react'; import { OntimeEvent } from 'ontime-types'; +import { useCallback } from 'react'; import * as Editor from '../../../common/components/editor-utils/EditorUtils'; import AppLink from '../../../common/components/link/app-link/AppLink'; import { useEntryActionsContext } from '../../../common/context/EntryActionsContext'; import useCustomFields from '../../../common/hooks-query/useCustomFields'; - import EntryEditorCustomFields from './composite/EventEditorCustomFields'; import EventEditorTimes from './composite/EventEditorTimes'; import EventEditorTitles from './composite/EventEditorTitles'; diff --git a/apps/client/src/features/rundown/entry-editor/EventEditorEmpty.tsx b/apps/client/src/features/rundown/entry-editor/EventEditorEmpty.tsx index 432ecd22a..0097de080 100644 --- a/apps/client/src/features/rundown/entry-editor/EventEditorEmpty.tsx +++ b/apps/client/src/features/rundown/entry-editor/EventEditorEmpty.tsx @@ -1,4 +1,4 @@ -import { memo, PropsWithChildren } from 'react'; +import { PropsWithChildren, memo } from 'react'; import * as Editor from '../../../common/components/editor-utils/EditorUtils'; import { deviceAlt, deviceMod } from '../../../common/utils/deviceUtils'; diff --git a/apps/client/src/features/rundown/entry-editor/GroupEditor.tsx b/apps/client/src/features/rundown/entry-editor/GroupEditor.tsx index ba59fbd43..9f447eba0 100644 --- a/apps/client/src/features/rundown/entry-editor/GroupEditor.tsx +++ b/apps/client/src/features/rundown/entry-editor/GroupEditor.tsx @@ -1,6 +1,6 @@ -import { useCallback } from 'react'; import { MaybeNumber, OntimeGroup } from 'ontime-types'; import { millisToString } from 'ontime-utils'; +import { useCallback } from 'react'; import * as Editor from '../../../common/components/editor-utils/EditorUtils'; import SwatchSelect from '../../../common/components/input/colour-input/SwatchSelect'; @@ -10,7 +10,6 @@ import useCustomFields from '../../../common/hooks-query/useCustomFields'; import { getOffsetState } from '../../../common/utils/offset'; import { cx, enDash, timerPlaceholder } from '../../../common/utils/styleUtils'; import TextLikeInput from '../../../views/cuesheet/cuesheet-table/cuesheet-table-elements/TextLikeInput'; - import EntryEditorCustomFields from './composite/EventEditorCustomFields'; import EventTextArea from './composite/EventTextArea'; import EntryEditorTextInput from './composite/EventTextInput'; diff --git a/apps/client/src/features/rundown/entry-editor/MilestoneEditor.tsx b/apps/client/src/features/rundown/entry-editor/MilestoneEditor.tsx index 4a3f39030..be69e2211 100644 --- a/apps/client/src/features/rundown/entry-editor/MilestoneEditor.tsx +++ b/apps/client/src/features/rundown/entry-editor/MilestoneEditor.tsx @@ -1,5 +1,5 @@ -import { useCallback } from 'react'; import { OntimeMilestone } from 'ontime-types'; +import { useCallback } from 'react'; import * as Editor from '../../../common/components/editor-utils/EditorUtils'; import SwatchSelect from '../../../common/components/input/colour-input/SwatchSelect'; @@ -7,7 +7,6 @@ import Input from '../../../common/components/input/input/Input'; import AppLink from '../../../common/components/link/app-link/AppLink'; import { useEntryActionsContext } from '../../../common/context/EntryActionsContext'; import useCustomFields from '../../../common/hooks-query/useCustomFields'; - import EntryEditorCustomFields from './composite/EventEditorCustomFields'; import EventTextArea from './composite/EventTextArea'; import EntryEditorTextInput from './composite/EventTextInput'; diff --git a/apps/client/src/features/rundown/entry-editor/RundownEntryEditor.tsx b/apps/client/src/features/rundown/entry-editor/RundownEntryEditor.tsx index 799f1eeca..2384186d2 100644 --- a/apps/client/src/features/rundown/entry-editor/RundownEntryEditor.tsx +++ b/apps/client/src/features/rundown/entry-editor/RundownEntryEditor.tsx @@ -1,9 +1,8 @@ +import { OntimeEntry, isOntimeEvent, isOntimeGroup, isOntimeMilestone } from 'ontime-types'; import { useMemo } from 'react'; -import { isOntimeEvent, isOntimeGroup, isOntimeMilestone, OntimeEntry } from 'ontime-types'; import useRundown from '../../../common/hooks-query/useRundown'; import { useEventSelection } from '../useEventSelection'; - import EventEditorFooter from './composite/EventEditorFooter'; import EventEditor from './EventEditor'; import EventEditorEmpty from './EventEditorEmpty'; diff --git a/apps/client/src/features/rundown/entry-editor/composite/EventEditorCustomFields.tsx b/apps/client/src/features/rundown/entry-editor/composite/EventEditorCustomFields.tsx index 51468b5fe..d2fc25210 100644 --- a/apps/client/src/features/rundown/entry-editor/composite/EventEditorCustomFields.tsx +++ b/apps/client/src/features/rundown/entry-editor/composite/EventEditorCustomFields.tsx @@ -1,9 +1,8 @@ -import { CSSProperties, Fragment } from 'react'; import { CustomFields, OntimeEvent, OntimeGroup, OntimeMilestone } from 'ontime-types'; +import { CSSProperties, Fragment } from 'react'; import { getAccessibleColour } from '../../../../common/utils/styleUtils'; import { EventEditorUpdateFields } from '../EventEditor'; - import EventEditorImage from './EventEditorImage'; import EventTextArea from './EventTextArea'; import EntryEditorTextInput from './EventTextInput'; diff --git a/apps/client/src/features/rundown/entry-editor/composite/EventEditorTimes.tsx b/apps/client/src/features/rundown/entry-editor/composite/EventEditorTimes.tsx index ef35126e8..0dfb7307c 100644 --- a/apps/client/src/features/rundown/entry-editor/composite/EventEditorTimes.tsx +++ b/apps/client/src/features/rundown/entry-editor/composite/EventEditorTimes.tsx @@ -1,7 +1,7 @@ +import { EndAction, TimeStrategy, TimerType } from 'ontime-types'; +import { millisToString, parseUserTime } from 'ontime-utils'; import { memo } from 'react'; import { IoInformationCircle } from 'react-icons/io5'; -import { EndAction, TimerType, TimeStrategy } from 'ontime-types'; -import { millisToString, parseUserTime } from 'ontime-utils'; import * as Editor from '../../../../common/components/editor-utils/EditorUtils'; import TimeInput from '../../../../common/components/input/time-input/TimeInput'; diff --git a/apps/client/src/features/rundown/entry-editor/composite/EventEditorTitles.tsx b/apps/client/src/features/rundown/entry-editor/composite/EventEditorTitles.tsx index 4cfaea9c3..902fd65f6 100644 --- a/apps/client/src/features/rundown/entry-editor/composite/EventEditorTitles.tsx +++ b/apps/client/src/features/rundown/entry-editor/composite/EventEditorTitles.tsx @@ -1,12 +1,11 @@ -import { memo } from 'react'; import { sanitiseCue } from 'ontime-utils'; +import { memo } from 'react'; import * as Editor from '../../../../common/components/editor-utils/EditorUtils'; import SwatchSelect from '../../../../common/components/input/colour-input/SwatchSelect'; import Input from '../../../../common/components/input/input/Input'; import Switch from '../../../../common/components/switch/Switch'; import { useEntryActionsContext } from '../../../../common/context/EntryActionsContext'; - import EventTextArea from './EventTextArea'; import EntryEditorTextInput from './EventTextInput'; diff --git a/apps/client/src/features/rundown/entry-editor/composite/EventEditorTriggers.module.scss b/apps/client/src/features/rundown/entry-editor/composite/EventEditorTriggers.module.scss index fc36726d6..5250d6901 100644 --- a/apps/client/src/features/rundown/entry-editor/composite/EventEditorTriggers.module.scss +++ b/apps/client/src/features/rundown/entry-editor/composite/EventEditorTriggers.module.scss @@ -27,4 +27,4 @@ .success { color: $green-500; -} \ No newline at end of file +} diff --git a/apps/client/src/features/rundown/entry-editor/composite/EventEditorTriggers.tsx b/apps/client/src/features/rundown/entry-editor/composite/EventEditorTriggers.tsx index 4b1d24876..ab2763a34 100644 --- a/apps/client/src/features/rundown/entry-editor/composite/EventEditorTriggers.tsx +++ b/apps/client/src/features/rundown/entry-editor/composite/EventEditorTriggers.tsx @@ -1,7 +1,7 @@ +import { TimerLifeCycle, Trigger, timerLifecycleValues } from 'ontime-types'; +import { generateId } from 'ontime-utils'; import { Fragment, useCallback, useMemo, useState } from 'react'; import { IoAlertCircle, IoCheckmarkCircle, IoTrash } from 'react-icons/io5'; -import { TimerLifeCycle, timerLifecycleValues, Trigger } from 'ontime-types'; -import { generateId } from 'ontime-utils'; import Button from '../../../../common/components/buttons/Button'; import IconButton from '../../../../common/components/buttons/IconButton'; @@ -10,7 +10,6 @@ import Tag from '../../../../common/components/tag/Tag'; import Tooltip from '../../../../common/components/tooltip/Tooltip'; import { useEntryActionsContext } from '../../../../common/context/EntryActionsContext'; import useAutomationSettings from '../../../../common/hooks-query/useAutomationSettings'; - import { eventTriggerOptions } from './eventTrigger.constants'; import style from './EventEditorTriggers.module.scss'; diff --git a/apps/client/src/features/rundown/entry-editor/composite/TargetDurationInput.tsx b/apps/client/src/features/rundown/entry-editor/composite/TargetDurationInput.tsx index d1c5bf7eb..b7709606b 100644 --- a/apps/client/src/features/rundown/entry-editor/composite/TargetDurationInput.tsx +++ b/apps/client/src/features/rundown/entry-editor/composite/TargetDurationInput.tsx @@ -1,5 +1,5 @@ -import { IoLockClosed, IoLockOpenOutline } from 'react-icons/io5'; import { MaybeNumber } from 'ontime-types'; +import { IoLockClosed, IoLockOpenOutline } from 'react-icons/io5'; import IconButton from '../../../../common/components/buttons/IconButton'; import * as Editor from '../../../../common/components/editor-utils/EditorUtils'; diff --git a/apps/client/src/features/rundown/entry-editor/quick-add-buttons/QuickAddButtons.tsx b/apps/client/src/features/rundown/entry-editor/quick-add-buttons/QuickAddButtons.tsx index a7b6a32c7..25e4c11d9 100644 --- a/apps/client/src/features/rundown/entry-editor/quick-add-buttons/QuickAddButtons.tsx +++ b/apps/client/src/features/rundown/entry-editor/quick-add-buttons/QuickAddButtons.tsx @@ -1,7 +1,7 @@ -import { memo } from 'react'; -import { IoAdd } from 'react-icons/io5'; import { Toolbar } from '@base-ui/react/toolbar'; import { MaybeString, SupportedEntry } from 'ontime-types'; +import { memo } from 'react'; +import { IoAdd } from 'react-icons/io5'; import Button from '../../../../common/components/buttons/Button'; import { useEntryActionsContext } from '../../../../common/context/EntryActionsContext'; diff --git a/apps/client/src/features/rundown/entry-editor/quick-add-cursor/QuickAddInline.tsx b/apps/client/src/features/rundown/entry-editor/quick-add-cursor/QuickAddInline.tsx index 95035f631..a90128930 100644 --- a/apps/client/src/features/rundown/entry-editor/quick-add-cursor/QuickAddInline.tsx +++ b/apps/client/src/features/rundown/entry-editor/quick-add-cursor/QuickAddInline.tsx @@ -1,6 +1,6 @@ +import { MaybeString, SupportedEntry } from 'ontime-types'; import { memo } from 'react'; import { IoAdd } from 'react-icons/io5'; -import { MaybeString, SupportedEntry } from 'ontime-types'; import IconButton from '../../../../common/components/buttons/IconButton'; import { DropdownMenu } from '../../../../common/components/dropdown-menu/DropdownMenu'; diff --git a/apps/client/src/features/rundown/hooks/useRundownCommands.ts b/apps/client/src/features/rundown/hooks/useRundownCommands.ts index baf52a81d..c4b2eb4d6 100644 --- a/apps/client/src/features/rundown/hooks/useRundownCommands.ts +++ b/apps/client/src/features/rundown/hooks/useRundownCommands.ts @@ -1,6 +1,6 @@ -import { useCallback } from 'react'; import { type EntryId, type OntimeEntry, type Rundown, SupportedEntry } from 'ontime-types'; import { getNextGroupNormal, getNextNormal, getPreviousGroupNormal, getPreviousNormal } from 'ontime-utils'; +import { useCallback } from 'react'; import type { useEntryActions } from '../../../common/hooks/useEntryAction'; import { useEntryCopy } from '../../../common/stores/entryCopyStore'; @@ -80,9 +80,9 @@ export function useRundownCommands({ } clone(entryCopyId, { - after: above ? undefined : normalisedAtId ?? undefined, + after: above ? undefined : (normalisedAtId ?? undefined), // if we don't have a cursor add the new event on top - before: above ? normalisedAtId ?? undefined : undefined, + before: above ? (normalisedAtId ?? undefined) : undefined, }); }, [entries, flatOrder, clone, reorderEntry], diff --git a/apps/client/src/features/rundown/hooks/useRundownDnd.ts b/apps/client/src/features/rundown/hooks/useRundownDnd.ts index c59dcb422..c883efd2d 100644 --- a/apps/client/src/features/rundown/hooks/useRundownDnd.ts +++ b/apps/client/src/features/rundown/hooks/useRundownDnd.ts @@ -1,7 +1,7 @@ -import { Dispatch, SetStateAction, useCallback, useMemo, useRef } from 'react'; import { DragEndEvent, DragOverEvent, DragStartEvent, PointerSensor, useSensor, useSensors } from '@dnd-kit/core'; -import { type EntryId, type Rundown, isOntimeGroup, SupportedEntry } from 'ontime-types'; +import { type EntryId, type Rundown, SupportedEntry, isOntimeGroup } from 'ontime-types'; import { reorderArray } from 'ontime-utils'; +import { Dispatch, SetStateAction, useCallback, useMemo, useRef } from 'react'; import type { useEntryActions } from '../../../common/hooks/useEntryAction'; import { canDrop } from '../rundown.utils'; diff --git a/apps/client/src/features/rundown/hooks/useRundownKeyboard.ts b/apps/client/src/features/rundown/hooks/useRundownKeyboard.ts index 13e2648a5..01d4c8fbf 100644 --- a/apps/client/src/features/rundown/hooks/useRundownKeyboard.ts +++ b/apps/client/src/features/rundown/hooks/useRundownKeyboard.ts @@ -1,5 +1,5 @@ import { useHotkeys } from '@mantine/hooks'; -import { type OntimeEntry, EntryId, SupportedEntry } from 'ontime-types'; +import { EntryId, type OntimeEntry, SupportedEntry } from 'ontime-types'; import { useEntryCopy } from '../../../common/stores/entryCopyStore'; import { useEventSelection } from '../useEventSelection'; diff --git a/apps/client/src/features/rundown/placements/FinderPlacement.tsx b/apps/client/src/features/rundown/placements/FinderPlacement.tsx index a03ab9679..65e72547b 100644 --- a/apps/client/src/features/rundown/placements/FinderPlacement.tsx +++ b/apps/client/src/features/rundown/placements/FinderPlacement.tsx @@ -1,5 +1,5 @@ -import { memo } from 'react'; import { useDisclosure, useHotkeys } from '@mantine/hooks'; +import { memo } from 'react'; import Finder from '../../../views/editor/finder/Finder'; diff --git a/apps/client/src/features/rundown/rundown-delay/DelayInput.module.scss b/apps/client/src/features/rundown/rundown-delay/DelayInput.module.scss index db1d5cae5..cd2e1a6ea 100644 --- a/apps/client/src/features/rundown/rundown-delay/DelayInput.module.scss +++ b/apps/client/src/features/rundown/rundown-delay/DelayInput.module.scss @@ -8,5 +8,5 @@ text-align: center; letter-spacing: 1px; max-width: 7em; - color: $ontime-delay-text + color: $ontime-delay-text; } diff --git a/apps/client/src/features/rundown/rundown-delay/DelayInput.tsx b/apps/client/src/features/rundown/rundown-delay/DelayInput.tsx index 2fed3ac24..396bfa044 100644 --- a/apps/client/src/features/rundown/rundown-delay/DelayInput.tsx +++ b/apps/client/src/features/rundown/rundown-delay/DelayInput.tsx @@ -1,9 +1,8 @@ -import { KeyboardEvent, useEffect, useRef, useState } from 'react'; import { millisToString, parseUserTime } from 'ontime-utils'; +import { KeyboardEvent, useEffect, useRef, useState } from 'react'; import Input from '../../../common/components/input/input/Input'; import { useEntryActionsContext } from '../../../common/context/EntryActionsContext'; - import BlockRadio from './BlockRadio'; import style from './DelayInput.module.scss'; diff --git a/apps/client/src/features/rundown/rundown-delay/RundownDelay.tsx b/apps/client/src/features/rundown/rundown-delay/RundownDelay.tsx index a1603d910..753a2166d 100644 --- a/apps/client/src/features/rundown/rundown-delay/RundownDelay.tsx +++ b/apps/client/src/features/rundown/rundown-delay/RundownDelay.tsx @@ -1,14 +1,13 @@ -import { useEffect, useRef } from 'react'; -import { IoCheckmarkDone, IoClose, IoReorderTwo } from 'react-icons/io5'; import { useSortable } from '@dnd-kit/sortable'; import { CSS } from '@dnd-kit/utilities'; import { OntimeDelay } from 'ontime-types'; +import { useEffect, useRef } from 'react'; +import { IoCheckmarkDone, IoClose, IoReorderTwo } from 'react-icons/io5'; import Button from '../../../common/components/buttons/Button'; import { useEntryActionsContext } from '../../../common/context/EntryActionsContext'; import { useEntryCopy } from '../../../common/stores/entryCopyStore'; import { cx } from '../../../common/utils/styleUtils'; - import DelayInput from './DelayInput'; import style from './RundownDelay.module.scss'; diff --git a/apps/client/src/features/rundown/rundown-event/RundownEvent.module.scss b/apps/client/src/features/rundown/rundown-event/RundownEvent.module.scss index 6e9e12bf0..1dd04a4e4 100644 --- a/apps/client/src/features/rundown/rundown-event/RundownEvent.module.scss +++ b/apps/client/src/features/rundown/rundown-event/RundownEvent.module.scss @@ -17,7 +17,7 @@ $skip-opacity: 0.2; 'binder ... ... ...'; grid-template-columns: $block-binder-width 3rem 1fr 3rem; - grid-template-rows: 0.125rem 2rem 2rem auto 0.125rem; + grid-template-rows: 0.125rem 2rem 2rem auto 0.125rem; align-items: center; padding-right: $block-clearance; gap: 2px; @@ -139,7 +139,7 @@ $skip-opacity: 0.2; } .eventTimers.editMode:hover { - [class*="hoverLabel"] { + [class*='hoverLabel'] { opacity: 1; transition: opacity 0.15s 0.5s ease; } diff --git a/apps/client/src/features/rundown/rundown-event/RundownEvent.tsx b/apps/client/src/features/rundown/rundown-event/RundownEvent.tsx index 6c498c0e1..506ee374a 100644 --- a/apps/client/src/features/rundown/rundown-event/RundownEvent.tsx +++ b/apps/client/src/features/rundown/rundown-event/RundownEvent.tsx @@ -1,3 +1,7 @@ +import { useSortable } from '@dnd-kit/sortable'; +import { CSS } from '@dnd-kit/utilities'; +import { Day, EndAction, EntryId, Playback, TimeStrategy, TimerType } from 'ontime-types'; +import { isPlaybackActive } from 'ontime-utils'; import { MouseEvent, useEffect, useRef } from 'react'; import { IoAdd, @@ -10,10 +14,6 @@ import { IoUnlink, } from 'react-icons/io5'; import { TbFlagFilled } from 'react-icons/tb'; -import { useSortable } from '@dnd-kit/sortable'; -import { CSS } from '@dnd-kit/utilities'; -import { Day, EndAction, EntryId, Playback, TimerType, TimeStrategy } from 'ontime-types'; -import { isPlaybackActive } from 'ontime-utils'; import { useEntryActionsContext } from '../../../common/context/EntryActionsContext'; import { useContextMenu } from '../../../common/hooks/useContextMenu'; @@ -22,7 +22,6 @@ import { deviceMod } from '../../../common/utils/deviceUtils'; import { cx, getAccessibleColour } from '../../../common/utils/styleUtils'; import { useEventIdSwapping } from '../useEventIdSwapping'; import { getSelectionMode, useEventSelection } from '../useEventSelection'; - import RundownEventInner from './RundownEventInner'; import RundownIndicators from './RundownIndicators'; diff --git a/apps/client/src/features/rundown/rundown-event/RundownEventInner.tsx b/apps/client/src/features/rundown/rundown-event/RundownEventInner.tsx index efd7bfcd5..74ee1673e 100644 --- a/apps/client/src/features/rundown/rundown-event/RundownEventInner.tsx +++ b/apps/client/src/features/rundown/rundown-event/RundownEventInner.tsx @@ -1,3 +1,4 @@ +import { Day, EndAction, Playback, TimeStrategy, TimerType } from 'ontime-types'; import { memo } from 'react'; import { IoArrowDown, @@ -10,7 +11,6 @@ import { IoTime, } from 'react-icons/io5'; import { LuArrowDownToLine } from 'react-icons/lu'; -import { Day, EndAction, Playback, TimerType, TimeStrategy } from 'ontime-types'; import Tooltip from '../../../common/components/tooltip/Tooltip'; import { cx } from '../../../common/utils/styleUtils'; @@ -18,7 +18,6 @@ import { AppMode } from '../../../ontimeConfig'; import TitleEditor from '../common/TitleEditor'; import TimeInputFlow from '../time-input-flow/TimeInputFlow'; import { useEditorFollowMode } from '../useEditorFollowMode'; - import RundownEventChip from './composite/RundownEventChip'; import EventBlockPlayback from './composite/RundownEventPlayback'; import EventBlockProgressBar from './composite/RundownEventProgressBar'; diff --git a/apps/client/src/features/rundown/rundown-event/composite/RundownEventChip.tsx b/apps/client/src/features/rundown/rundown-event/composite/RundownEventChip.tsx index c4edc86c5..55cde6fcd 100644 --- a/apps/client/src/features/rundown/rundown-event/composite/RundownEventChip.tsx +++ b/apps/client/src/features/rundown/rundown-event/composite/RundownEventChip.tsx @@ -1,11 +1,11 @@ +import { Day } from 'ontime-types'; +import { MILLIS_PER_MINUTE, MILLIS_PER_SECOND, isPlaybackActive, millisToString } from 'ontime-utils'; import { useMemo } from 'react'; import { IoCheckmarkCircle } from 'react-icons/io5'; -import { Day } from 'ontime-types'; -import { isPlaybackActive, MILLIS_PER_MINUTE, MILLIS_PER_SECOND, millisToString } from 'ontime-utils'; import Tooltip from '../../../../common/components/tooltip/Tooltip'; -import { usePlayback } from '../../../../common/hooks/useSocket'; import useReport from '../../../../common/hooks-query/useReport'; +import { usePlayback } from '../../../../common/hooks/useSocket'; import { cx } from '../../../../common/utils/styleUtils'; import { formatDuration, useTimeUntilExpectedStart } from '../../../../common/utils/time'; diff --git a/apps/client/src/features/rundown/rundown-event/composite/RundownEventPlayback.tsx b/apps/client/src/features/rundown/rundown-event/composite/RundownEventPlayback.tsx index 6a3aebe5a..c042a9e75 100644 --- a/apps/client/src/features/rundown/rundown-event/composite/RundownEventPlayback.tsx +++ b/apps/client/src/features/rundown/rundown-event/composite/RundownEventPlayback.tsx @@ -1,4 +1,4 @@ -import { memo, MouseEvent } from 'react'; +import { MouseEvent, memo } from 'react'; import { IoPause, IoPlay, IoReload, IoRemoveCircle, IoRemoveCircleOutline } from 'react-icons/io5'; import IconButton from '../../../../common/components/buttons/IconButton'; diff --git a/apps/client/src/features/rundown/rundown-group/RundownGroup.tsx b/apps/client/src/features/rundown/rundown-group/RundownGroup.tsx index 3cbef6d64..1db4796ad 100644 --- a/apps/client/src/features/rundown/rundown-group/RundownGroup.tsx +++ b/apps/client/src/features/rundown/rundown-group/RundownGroup.tsx @@ -1,3 +1,7 @@ +import { useSortable } from '@dnd-kit/sortable'; +import { CSS } from '@dnd-kit/utilities'; +import { EntryId, OntimeGroup } from 'ontime-types'; +import { MILLIS_PER_MINUTE, millisToString } from 'ontime-utils'; import { MouseEvent, useRef } from 'react'; import { IoChevronDown, @@ -7,10 +11,6 @@ import { IoReorderTwo, IoTrash, } from 'react-icons/io5'; -import { useSortable } from '@dnd-kit/sortable'; -import { CSS } from '@dnd-kit/utilities'; -import { EntryId, OntimeGroup } from 'ontime-types'; -import { MILLIS_PER_MINUTE, millisToString } from 'ontime-utils'; import IconButton from '../../../common/components/buttons/IconButton'; import Tag from '../../../common/components/tag/Tag'; diff --git a/apps/client/src/features/rundown/rundown-header/RundownHeader.tsx b/apps/client/src/features/rundown/rundown-header/RundownHeader.tsx index eac8ce2a0..d7316211c 100644 --- a/apps/client/src/features/rundown/rundown-header/RundownHeader.tsx +++ b/apps/client/src/features/rundown/rundown-header/RundownHeader.tsx @@ -1,8 +1,8 @@ -import { memo } from 'react'; import { Toggle } from '@base-ui/react/toggle'; import { ToggleGroup } from '@base-ui/react/toggle-group'; import { Toolbar } from '@base-ui/react/toolbar'; import { OffsetMode } from 'ontime-types'; +import { memo } from 'react'; import Tooltip from '../../../common/components/tooltip/Tooltip'; import { setOffsetMode, useOffsetMode } from '../../../common/hooks/useSocket'; @@ -10,7 +10,6 @@ import { AppMode } from '../../../ontimeConfig'; import { EditorLayoutMode, useEditorLayout } from '../../../views/editor/useEditorLayout'; import { RundownViewMode } from '../rundown.options'; import { useEditorFollowMode } from '../useEditorFollowMode'; - import RundownMenu from './RundownMenu'; import style from './RundownHeader.module.scss'; diff --git a/apps/client/src/features/rundown/rundown-header/RundownHeaderMobile.tsx b/apps/client/src/features/rundown/rundown-header/RundownHeaderMobile.tsx index 07e6d5e0d..1c6577a04 100644 --- a/apps/client/src/features/rundown/rundown-header/RundownHeaderMobile.tsx +++ b/apps/client/src/features/rundown/rundown-header/RundownHeaderMobile.tsx @@ -1,7 +1,7 @@ -import { memo } from 'react'; import { Toggle } from '@base-ui/react/toggle'; import { ToggleGroup } from '@base-ui/react/toggle-group'; import { Toolbar } from '@base-ui/react/toolbar'; +import { memo } from 'react'; import { AppMode } from '../../../ontimeConfig'; import { RundownViewMode } from '../rundown.options'; diff --git a/apps/client/src/features/rundown/rundown-header/RundownMenu.tsx b/apps/client/src/features/rundown/rundown-header/RundownMenu.tsx index f48bd1c43..6ba5250ef 100644 --- a/apps/client/src/features/rundown/rundown-header/RundownMenu.tsx +++ b/apps/client/src/features/rundown/rundown-header/RundownMenu.tsx @@ -1,7 +1,7 @@ -import { memo, useCallback } from 'react'; -import { IoEllipsisHorizontal, IoList, IoTrash } from 'react-icons/io5'; import { Toolbar } from '@base-ui/react/toolbar'; import { useDisclosure } from '@mantine/hooks'; +import { memo, useCallback } from 'react'; +import { IoEllipsisHorizontal, IoList, IoTrash } from 'react-icons/io5'; import Button from '../../../common/components/buttons/Button'; import IconButton from '../../../common/components/buttons/IconButton'; diff --git a/apps/client/src/features/rundown/rundown-milestone/RundownMilestone.tsx b/apps/client/src/features/rundown/rundown-milestone/RundownMilestone.tsx index 006f3a069..35516f35b 100644 --- a/apps/client/src/features/rundown/rundown-milestone/RundownMilestone.tsx +++ b/apps/client/src/features/rundown/rundown-milestone/RundownMilestone.tsx @@ -1,8 +1,8 @@ -import { MouseEvent, useCallback, useRef } from 'react'; -import { IoReorderTwo, IoTrash } from 'react-icons/io5'; import { useSortable } from '@dnd-kit/sortable'; import { CSS } from '@dnd-kit/utilities'; import { EntryId } from 'ontime-types'; +import { MouseEvent, useCallback, useRef } from 'react'; +import { IoReorderTwo, IoTrash } from 'react-icons/io5'; import Input from '../../../common/components/input/input/Input'; import useReactiveTextInput from '../../../common/components/input/text-input/useReactiveTextInput'; diff --git a/apps/client/src/features/rundown/rundown-table/RundownTable.tsx b/apps/client/src/features/rundown/rundown-table/RundownTable.tsx index cfdbb0428..e943f3b98 100644 --- a/apps/client/src/features/rundown/rundown-table/RundownTable.tsx +++ b/apps/client/src/features/rundown/rundown-table/RundownTable.tsx @@ -6,7 +6,6 @@ import CuesheetDnd from '../../../views/cuesheet/cuesheet-dnd/CuesheetDnd'; import CuesheetTable from '../../../views/cuesheet/cuesheet-table/CuesheetTable'; import { useCuesheetPermissions } from '../../../views/cuesheet/useTablePermissions'; import { useEditorFollowMode } from '../useEditorFollowMode'; - import { makeRundownColumns } from './makeRundownColumns'; export default memo(RundownTable); diff --git a/apps/client/src/features/rundown/rundown.utils.ts b/apps/client/src/features/rundown/rundown.utils.ts index ee7092e7d..3f8e72d2f 100644 --- a/apps/client/src/features/rundown/rundown.utils.ts +++ b/apps/client/src/features/rundown/rundown.utils.ts @@ -1,4 +1,4 @@ -import { EntryId, isOntimeGroup, RundownEntries, SupportedEntry } from 'ontime-types'; +import { EntryId, RundownEntries, SupportedEntry, isOntimeGroup } from 'ontime-types'; /** * Creates a sortable list of entries diff --git a/apps/client/src/features/rundown/time-input-flow/TimeInputFlow.module.scss b/apps/client/src/features/rundown/time-input-flow/TimeInputFlow.module.scss index de55d89a8..1c8b144b9 100644 --- a/apps/client/src/features/rundown/time-input-flow/TimeInputFlow.module.scss +++ b/apps/client/src/features/rundown/time-input-flow/TimeInputFlow.module.scss @@ -29,7 +29,7 @@ left: 0; opacity: 0; border-radius: $component-border-radius-md; - transition: opacity 0.15s ease; // no delay on fade out + transition: opacity 0.15s ease; // no delay on fade out pointer-events: none; z-index: $zindex-floating; diff --git a/apps/client/src/features/rundown/time-input-flow/TimeInputFlow.tsx b/apps/client/src/features/rundown/time-input-flow/TimeInputFlow.tsx index ecd3a11f5..a2edabcfa 100644 --- a/apps/client/src/features/rundown/time-input-flow/TimeInputFlow.tsx +++ b/apps/client/src/features/rundown/time-input-flow/TimeInputFlow.tsx @@ -1,14 +1,13 @@ -import { memo } from 'react'; -import { IoAlertCircleOutline, IoLink, IoLockClosed, IoLockOpenOutline, IoUnlink } from 'react-icons/io5'; import { TimeField, TimeStrategy } from 'ontime-types'; import { dayInMs } from 'ontime-utils'; +import { memo } from 'react'; +import { IoAlertCircleOutline, IoLink, IoLockClosed, IoLockOpenOutline, IoUnlink } from 'react-icons/io5'; import IconButton from '../../../common/components/buttons/IconButton'; import * as Editor from '../../../common/components/editor-utils/EditorUtils'; import TimeInput from '../../../common/components/input/time-input/TimeInput'; import Tooltip from '../../../common/components/tooltip/Tooltip'; import { useEntryActionsContext } from '../../../common/context/EntryActionsContext'; - import TimeInputGroup from './TimeInputGroup'; import style from './TimeInputFlow.module.scss'; diff --git a/apps/client/src/features/rundown/useCollapsedGroups.ts b/apps/client/src/features/rundown/useCollapsedGroups.ts index d23ee182d..4ff1a509d 100644 --- a/apps/client/src/features/rundown/useCollapsedGroups.ts +++ b/apps/client/src/features/rundown/useCollapsedGroups.ts @@ -1,6 +1,6 @@ -import { useCallback, useMemo } from 'react'; import { useSessionStorage } from '@mantine/hooks'; import { EntryId } from 'ontime-types'; +import { useCallback, useMemo } from 'react'; /** * Keeps track of which groups are collapsed diff --git a/apps/client/src/features/rundown/useEventSelection.ts b/apps/client/src/features/rundown/useEventSelection.ts index 75ea7235f..ef3fd3fa3 100644 --- a/apps/client/src/features/rundown/useEventSelection.ts +++ b/apps/client/src/features/rundown/useEventSelection.ts @@ -1,5 +1,5 @@ +import { EntryId, MaybeNumber, Rundown, isOntimeEvent } from 'ontime-types'; import { MouseEvent } from 'react'; -import { EntryId, isOntimeEvent, MaybeNumber, Rundown } from 'ontime-types'; import { create } from 'zustand'; import { RUNDOWN } from '../../common/api/constants'; diff --git a/apps/client/src/features/rundown/useSelectAndRevealEntry.ts b/apps/client/src/features/rundown/useSelectAndRevealEntry.ts index ee878187c..8db177c5c 100644 --- a/apps/client/src/features/rundown/useSelectAndRevealEntry.ts +++ b/apps/client/src/features/rundown/useSelectAndRevealEntry.ts @@ -1,5 +1,5 @@ -import { useCallback } from 'react'; import { EntryId, MaybeString } from 'ontime-types'; +import { useCallback } from 'react'; import { useCollapsedGroups } from './useCollapsedGroups'; import { useEventSelection } from './useEventSelection'; diff --git a/apps/client/src/features/sharing/GenerateLinkForm.tsx b/apps/client/src/features/sharing/GenerateLinkForm.tsx index f07eb19f3..e0555b773 100644 --- a/apps/client/src/features/sharing/GenerateLinkForm.tsx +++ b/apps/client/src/features/sharing/GenerateLinkForm.tsx @@ -1,8 +1,8 @@ +import { OntimeView, URLPreset } from 'ontime-types'; +import { generateId } from 'ontime-utils'; import { useRef, useState } from 'react'; import { FieldErrors, useForm } from 'react-hook-form'; import QRCode from 'react-qr-code'; -import { OntimeView, URLPreset } from 'ontime-types'; -import { generateId } from 'ontime-utils'; import { generateUrl } from '../../common/api/session'; import { maybeAxiosError } from '../../common/api/utils'; @@ -18,7 +18,6 @@ import { preventEscape } from '../../common/utils/keyEvent'; import { isUrlSafe } from '../../common/utils/regex'; import { isOntimeCloud, serverURL } from '../../externals'; import * as Panel from '../app-settings/panel-utils/PanelUtils'; - import CuesheetLinkOptions from './composite/CuesheetLinkOptions'; import style from './GenerateLinkForm.module.scss'; diff --git a/apps/client/src/features/sharing/GenerateLinkFormExport.tsx b/apps/client/src/features/sharing/GenerateLinkFormExport.tsx index 21d69a90a..ca0f31050 100644 --- a/apps/client/src/features/sharing/GenerateLinkFormExport.tsx +++ b/apps/client/src/features/sharing/GenerateLinkFormExport.tsx @@ -1,9 +1,8 @@ -import { useMemo } from 'react'; import { OntimeView } from 'ontime-types'; +import { useMemo } from 'react'; import useInfo from '../../common/hooks-query/useInfo'; import useUrlPresets from '../../common/hooks-query/useUrlPresets'; - import GenerateLinkForm from './GenerateLinkForm'; interface GenerateLinkFormExportProps { diff --git a/apps/client/src/features/sharing/composite/CuesheetLinkOptions.module.scss b/apps/client/src/features/sharing/composite/CuesheetLinkOptions.module.scss index 4de828e96..ba3a3ade5 100644 --- a/apps/client/src/features/sharing/composite/CuesheetLinkOptions.module.scss +++ b/apps/client/src/features/sharing/composite/CuesheetLinkOptions.module.scss @@ -15,4 +15,4 @@ .inline { display: flex; gap: 0.5rem; -} \ No newline at end of file +} diff --git a/apps/client/src/index.scss b/apps/client/src/index.scss index 0b85136b7..3a719f98d 100644 --- a/apps/client/src/index.scss +++ b/apps/client/src/index.scss @@ -9,8 +9,9 @@ src: url(@fontsource/open-sans/files/open-sans-latin-300-normal.woff2) format('woff2'), url(@fontsource/open-sans/files/open-sans-latin-300-normal.woff) format('woff'); - unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, - U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; + unicode-range: + U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, + U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; } /* open-sans-latin-400-normal */ @@ -22,8 +23,9 @@ src: url(@fontsource/open-sans/files/open-sans-latin-400-normal.woff2) format('woff2'), url(@fontsource/open-sans/files/open-sans-latin-400-normal.woff) format('woff'); - unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, - U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; + unicode-range: + U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, + U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; } /* open-sans-latin-600-normal */ @@ -35,8 +37,9 @@ src: url(@fontsource/open-sans/files/open-sans-latin-600-normal.woff2) format('woff2'), url(@fontsource/open-sans/files/open-sans-latin-600-normal.woff) format('woff'); - unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, - U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; + unicode-range: + U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, + U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; } $track-color: $white-1; diff --git a/apps/client/src/sentry.config.ts b/apps/client/src/sentry.config.ts index 2d1e99010..a0372ad5b 100644 --- a/apps/client/src/sentry.config.ts +++ b/apps/client/src/sentry.config.ts @@ -1,6 +1,6 @@ -import React from 'react'; -import { createRoutesFromChildren, matchRoutes, Routes, useLocation, useNavigationType } from 'react-router'; import * as Sentry from '@sentry/react'; +import React from 'react'; +import { Routes, createRoutesFromChildren, matchRoutes, useLocation, useNavigationType } from 'react-router'; import { ONTIME_VERSION } from './ONTIME_VERSION'; diff --git a/apps/client/src/theme/_mixins.scss b/apps/client/src/theme/_mixins.scss index 4998a6bbd..7e8b23fe5 100644 --- a/apps/client/src/theme/_mixins.scss +++ b/apps/client/src/theme/_mixins.scss @@ -10,7 +10,7 @@ @mixin rotate-fourty-five { transform: rotate(45deg); -} +} .fourtyfive { @include rotate-fourty-five; diff --git a/apps/client/src/theme/_ontimeColours.scss b/apps/client/src/theme/_ontimeColours.scss index 97775c9f7..c8c56487a 100644 --- a/apps/client/src/theme/_ontimeColours.scss +++ b/apps/client/src/theme/_ontimeColours.scss @@ -5,15 +5,15 @@ $white-2: rgba(255, 255, 255, 0.02); $white-3: rgba(255, 255, 255, 0.03); $white-7: rgba(255, 255, 255, 0.07); $white-9: rgba(255, 255, 255, 0.09); -$white-10: rgba(255, 255, 255, 0.10); +$white-10: rgba(255, 255, 255, 0.1); $white-13: rgba(255, 255, 255, 0.13); -$white-20: rgba(255, 255, 255, 0.20); -$white-40: rgba(255, 255, 255, 0.40); -$white-60: rgba(255, 255, 255, 0.60); -$white-90: rgba(255, 255, 255, 0.90); +$white-20: rgba(255, 255, 255, 0.2); +$white-40: rgba(255, 255, 255, 0.4); +$white-60: rgba(255, 255, 255, 0.6); +$white-90: rgba(255, 255, 255, 0.9); -$black-10: rgba(0, 0, 0, 0.10); -$black-60: rgba(0, 0, 0, 0.60); +$black-10: rgba(0, 0, 0, 0.1); +$black-60: rgba(0, 0, 0, 0.6); $gray-50: #f6f6f6; $gray-100: #ececec; @@ -36,82 +36,82 @@ $gray-1350: #101010; $ui-white: $gray-50; $ui-black: $gray-1350; -$orange-50: #FFFAF0; -$orange-100: #FFF4DF; -$orange-200: #FFEECE; -$orange-300: #FFE1AB; -$orange-400: #FFCC78; -$orange-500: #FFBC56; -$orange-600: #FFAB33; -$orange-700: #E69000; -$orange-800: #D27C00; -$orange-900: #B46D00; -$orange-1000: #975E00; -$orange-1100: #6A4400; -$orange-1200: #4C3200; -$orange-1300: #3D2900; -$orange-1350: #2E1F00; +$orange-50: #fffaf0; +$orange-100: #fff4df; +$orange-200: #ffeece; +$orange-300: #ffe1ab; +$orange-400: #ffcc78; +$orange-500: #ffbc56; +$orange-600: #ffab33; +$orange-700: #e69000; +$orange-800: #d27c00; +$orange-900: #b46d00; +$orange-1000: #975e00; +$orange-1100: #6a4400; +$orange-1200: #4c3200; +$orange-1300: #3d2900; +$orange-1350: #2e1f00; -$green-50: #EDFAEE; -$green-100: #DCF4DE; -$green-200: #CBEECF; -$green-300: #A9E0B0; -$green-400: #77C785; -$green-500: #55B469; -$green-600: #339E4E; -$green-700: #087A27; -$green-800: #006E1B; +$green-50: #edfaee; +$green-100: #dcf4de; +$green-200: #cbeecf; +$green-300: #a9e0b0; +$green-400: #77c785; +$green-500: #55b469; +$green-600: #339e4e; +$green-700: #087a27; +$green-800: #006e1b; $green-900: #006415; -$green-1000: #00570F; +$green-1000: #00570f; $green-1100: #004108; $green-1200: #003005; $green-1300: #002703; -$green-1350: #001D02; +$green-1350: #001d02; -$blue-50: #F5F7FF; -$blue-100: #E3EAFF; -$blue-200: #D2DDFF; -$blue-300: #AFC4FF; -$blue-400: #779BE7; -$blue-500: #578AF4; -$blue-600: #3E75E8; -$blue-700: #2B5ABC; -$blue-800: #0A43B9; -$blue-900: #0036A6; -$blue-1000: #002A90; -$blue-1100: #001A64; +$blue-50: #f5f7ff; +$blue-100: #e3eaff; +$blue-200: #d2ddff; +$blue-300: #afc4ff; +$blue-400: #779be7; +$blue-500: #578af4; +$blue-600: #3e75e8; +$blue-700: #2b5abc; +$blue-800: #0a43b9; +$blue-900: #0036a6; +$blue-1000: #002a90; +$blue-1100: #001a64; $blue-1200: #001145; -$blue-1300: #000D36; +$blue-1300: #000d36; $blue-1350: #000926; -$red-50: #FFF0F0; -$red-100: #FFDFDF; -$red-200: #FFCECE; -$red-300: #FFABAB; -$red-400: #FF7878; -$red-500: #FA5656; -$red-600: #ED3333; -$red-700: #D20300; -$red-800: #C10000; -$red-900: #B20000; -$red-1000: #9A0000; -$red-1100: #6F0000; +$red-50: #fff0f0; +$red-100: #ffdfdf; +$red-200: #ffcece; +$red-300: #ffabab; +$red-400: #ff7878; +$red-500: #fa5656; +$red-600: #ed3333; +$red-700: #d20300; +$red-800: #c10000; +$red-900: #b20000; +$red-1000: #9a0000; +$red-1100: #6f0000; $red-1200: #520000; $red-1300: #440000; $red-1350: #360000; -$violet-50: #F6F6F6; -$violet-100: #EBE5FF; -$violet-200: #DFD5FF; -$violet-300: #C7B8FD; -$violet-400: #A790F5; -$violet-500: #9379EC; -$violet-600: #8064E1; -$violet-700: #674ACB; -$violet-800: #4E31B1; -$violet-900: #3F249D; +$violet-50: #f6f6f6; +$violet-100: #ebe5ff; +$violet-200: #dfd5ff; +$violet-300: #c7b8fd; +$violet-400: #a790f5; +$violet-500: #9379ec; +$violet-600: #8064e1; +$violet-700: #674acb; +$violet-800: #4e31b1; +$violet-900: #3f249d; $violet-1000: #311887; -$violet-1100: #1F0B62; +$violet-1100: #1f0b62; $violet-1200: #140545; -$violet-1300: #0F0336; -$violet-1350: #0A0126; +$violet-1300: #0f0336; +$violet-1350: #0a0126; diff --git a/apps/client/src/theme/_ontimeStyles.scss b/apps/client/src/theme/_ontimeStyles.scss index 8ad665a79..f43863f96 100644 --- a/apps/client/src/theme/_ontimeStyles.scss +++ b/apps/client/src/theme/_ontimeStyles.scss @@ -1,4 +1,4 @@ -@use "./ontimeColours" as *; +@use './ontimeColours' as *; $transition-time-action: 0.1s; $transition-time-feedback: 0.3s; @@ -33,16 +33,16 @@ $active-green: $green-700; // playback colours $playback-start: $green-600; $ontime-roll: #22a0e9; -$ontime-delay: #F57C13; -$ontime-delay-text: #E69056; +$ontime-delay: #f57c13; +$ontime-delay-text: #e69056; $ontime-paused: #c05621; -$ontime-stop: #E4281E; +$ontime-stop: #e4281e; $playback-negative: $red-500; $playback-ahead: $green-500; $active-indicator: $green-400; $text-black: $gray-1350; -$playback-over: #F57C13; +$playback-over: #f57c13; $playback-under: $green-500; // interface panels @@ -65,7 +65,7 @@ $section-spacing: 1rem; $main-spacing: 2rem; // interface text -$ontime-font-family: "Open Sans", "Segoe UI", sans-serif; +$ontime-font-family: 'Open Sans', 'Segoe UI', sans-serif; $title-gray: $gray-200; $label-gray: $gray-600; $secondary-text-gray: $gray-400; diff --git a/apps/client/src/translation/TranslationProvider.tsx b/apps/client/src/translation/TranslationProvider.tsx index 96c43d9ca..2ed6a8b9c 100644 --- a/apps/client/src/translation/TranslationProvider.tsx +++ b/apps/client/src/translation/TranslationProvider.tsx @@ -1,10 +1,9 @@ -import { createContext, PropsWithChildren, useCallback, useContext } from 'react'; -import { langEn, TranslationObject } from 'ontime-types'; +import { TranslationObject, langEn } from 'ontime-types'; +import { PropsWithChildren, createContext, useCallback, useContext } from 'react'; import { postUserTranslation } from '../common/api/assets'; import { useCustomTranslation } from '../common/hooks-query/useCustomTranslation'; import useSettings from '../common/hooks-query/useSettings'; - import { langDe } from './languages/de'; import { langEs } from './languages/es'; import { langFr } from './languages/fr'; diff --git a/apps/client/src/views/ViewLoader.tsx b/apps/client/src/views/ViewLoader.tsx index 9c78db19b..2b72c03a7 100644 --- a/apps/client/src/views/ViewLoader.tsx +++ b/apps/client/src/views/ViewLoader.tsx @@ -1,9 +1,8 @@ import { PropsWithChildren } from 'react'; import { overrideStylesURL } from '../common/api/constants'; -import { useRuntimeStylesheet } from '../common/hooks/useRuntimeStylesheet'; import useViewSettings from '../common/hooks-query/useViewSettings'; - +import { useRuntimeStylesheet } from '../common/hooks/useRuntimeStylesheet'; import Loader from './common/loader/Loader'; export default function ViewLoader({ children }: PropsWithChildren) { diff --git a/apps/client/src/views/backstage/Backstage.tsx b/apps/client/src/views/backstage/Backstage.tsx index 35ffaacc3..0dd7c35ab 100644 --- a/apps/client/src/views/backstage/Backstage.tsx +++ b/apps/client/src/views/backstage/Backstage.tsx @@ -1,8 +1,8 @@ -import { useEffect, useMemo, useState } from 'react'; -import QRCode from 'react-qr-code'; import { useViewportSize } from '@mantine/hooks'; import { OntimeView, ProjectData } from 'ontime-types'; import { millisToString, removeLeadingZero } from 'ontime-utils'; +import { useEffect, useMemo, useState } from 'react'; +import QRCode from 'react-qr-code'; import ProgressBar from '../../common/components/progress-bar/ProgressBar'; import Empty from '../../common/components/state/Empty'; @@ -18,7 +18,6 @@ import { useTranslation } from '../../translation/TranslationProvider'; import Loader from '../common/loader/Loader'; import ScheduleExport from '../common/schedule/ScheduleExport'; import SuperscriptTime from '../common/superscript-time/SuperscriptTime'; - import { getBackstageOptions, useBackstageOptions } from './backstage.options'; import { getCardData, getIsPendingStart, getShowProgressBar, isOvertime } from './backstage.utils'; import { BackstageData, useBackstageData } from './useBackstageData'; diff --git a/apps/client/src/views/backstage/backstage.options.ts b/apps/client/src/views/backstage/backstage.options.ts index a60545787..2e7cf1ddd 100644 --- a/apps/client/src/views/backstage/backstage.options.ts +++ b/apps/client/src/views/backstage/backstage.options.ts @@ -1,6 +1,6 @@ +import { CustomFields, OntimeEvent, ProjectData } from 'ontime-types'; import { use, useMemo } from 'react'; import { useSearchParams } from 'react-router'; -import { CustomFields, OntimeEvent, ProjectData } from 'ontime-types'; import { getTimeOption } from '../../common/components/view-params-editor/common.options'; import { OptionTitle } from '../../common/components/view-params-editor/constants'; diff --git a/apps/client/src/views/backstage/useBackstageData.ts b/apps/client/src/views/backstage/useBackstageData.ts index 330f1fcb3..1a804edac 100644 --- a/apps/client/src/views/backstage/useBackstageData.ts +++ b/apps/client/src/views/backstage/useBackstageData.ts @@ -5,7 +5,7 @@ import useProjectData from '../../common/hooks-query/useProjectData'; import { useFlatRundown } from '../../common/hooks-query/useRundown'; import useSettings from '../../common/hooks-query/useSettings'; import { useViewOptionsStore } from '../../common/stores/viewOptions'; -import { aggregateQueryStatus, ViewData } from '../utils/viewLoader.utils'; +import { ViewData, aggregateQueryStatus } from '../utils/viewLoader.utils'; export interface BackstageData { events: OntimeEntry[]; diff --git a/apps/client/src/views/common/schedule/Schedule.tsx b/apps/client/src/views/common/schedule/Schedule.tsx index 070fad599..9f89f81b3 100644 --- a/apps/client/src/views/common/schedule/Schedule.tsx +++ b/apps/client/src/views/common/schedule/Schedule.tsx @@ -1,5 +1,4 @@ import { cx } from '../../../common/utils/styleUtils'; - import { useSchedule } from './ScheduleContext'; import ScheduleItem from './ScheduleItem'; diff --git a/apps/client/src/views/common/schedule/ScheduleContext.tsx b/apps/client/src/views/common/schedule/ScheduleContext.tsx index d2c9cc214..7359b16a2 100644 --- a/apps/client/src/views/common/schedule/ScheduleContext.tsx +++ b/apps/client/src/views/common/schedule/ScheduleContext.tsx @@ -1,7 +1,8 @@ +import { EntryId, OntimeEntry, OntimeEvent, isOntimeEvent } from 'ontime-types'; import { - createContext, PropsWithChildren, RefObject, + createContext, use, useCallback, useEffect, @@ -9,11 +10,9 @@ import { useRef, useState, } from 'react'; -import { EntryId, isOntimeEvent, OntimeEntry, OntimeEvent } from 'ontime-types'; import { usePartialRundown } from '../../../common/hooks-query/useRundown'; import { ExtendedEntry } from '../../../common/utils/rundownMetadata'; - import { useScheduleOptions } from './schedule.options'; interface ScheduleContextState { diff --git a/apps/client/src/views/common/schedule/ScheduleExport.tsx b/apps/client/src/views/common/schedule/ScheduleExport.tsx index 898cb2d81..5442a6939 100644 --- a/apps/client/src/views/common/schedule/ScheduleExport.tsx +++ b/apps/client/src/views/common/schedule/ScheduleExport.tsx @@ -1,5 +1,5 @@ -import { memo } from 'react'; import { MaybeString } from 'ontime-types'; +import { memo } from 'react'; import Schedule from './Schedule'; import { ScheduleProvider } from './ScheduleContext'; diff --git a/apps/client/src/views/common/schedule/ScheduleItem.tsx b/apps/client/src/views/common/schedule/ScheduleItem.tsx index 47770d55e..3dbf90006 100644 --- a/apps/client/src/views/common/schedule/ScheduleItem.tsx +++ b/apps/client/src/views/common/schedule/ScheduleItem.tsx @@ -6,7 +6,6 @@ import { ExtendedEntry } from '../../../common/utils/rundownMetadata'; import { cx } from '../../../common/utils/styleUtils'; import { formatTime, getExpectedTimesFromExtendedEvent } from '../../../common/utils/time'; import SuperscriptPeriod from '../superscript-time/SuperscriptPeriod'; - import { useScheduleOptions } from './schedule.options'; import './Schedule.scss'; diff --git a/apps/client/src/views/common/schedule/ScheduleNav.tsx b/apps/client/src/views/common/schedule/ScheduleNav.tsx index 1602b0834..6e158cc3c 100644 --- a/apps/client/src/views/common/schedule/ScheduleNav.tsx +++ b/apps/client/src/views/common/schedule/ScheduleNav.tsx @@ -1,5 +1,4 @@ import { cx } from '../../../common/utils/styleUtils'; - import { useSchedule } from './ScheduleContext'; import './Schedule.scss'; diff --git a/apps/client/src/views/countdown/Countdown.tsx b/apps/client/src/views/countdown/Countdown.tsx index 17192729b..b26240b76 100644 --- a/apps/client/src/views/countdown/Countdown.tsx +++ b/apps/client/src/views/countdown/Countdown.tsx @@ -1,6 +1,6 @@ +import { EntryId, OntimeEvent, OntimeView, PlayableEvent, isOntimeEvent, isPlayableEvent } from 'ontime-types'; import { useMemo, useState } from 'react'; import { IoAdd } from 'react-icons/io5'; -import { EntryId, isOntimeEvent, isPlayableEvent, OntimeEvent, OntimeView, PlayableEvent } from 'ontime-types'; import Button from '../../common/components/buttons/Button'; import Empty from '../../common/components/state/Empty'; @@ -14,7 +14,6 @@ import { formatTime, getDefaultFormat } from '../../common/utils/time'; import { useTranslation } from '../../translation/TranslationProvider'; import Loader from '../common/loader/Loader'; import SuperscriptTime from '../common/superscript-time/SuperscriptTime'; - import { getCountdownOptions, useCountdownOptions } from './countdown.options'; import { getOrderedSubscriptions } from './countdown.utils'; import CountdownSelect from './CountdownSelect'; diff --git a/apps/client/src/views/countdown/CountdownSelect.tsx b/apps/client/src/views/countdown/CountdownSelect.tsx index 28830ac2c..c36ce0fd8 100644 --- a/apps/client/src/views/countdown/CountdownSelect.tsx +++ b/apps/client/src/views/countdown/CountdownSelect.tsx @@ -1,13 +1,12 @@ +import { EntryId, PlayableEvent } from 'ontime-types'; import { useState } from 'react'; import { IoArrowBack, IoClose, IoSaveOutline } from 'react-icons/io5'; import { useNavigate } from 'react-router'; -import { EntryId, PlayableEvent } from 'ontime-types'; import Button from '../../common/components/buttons/Button'; import { ExtendedEntry } from '../../common/utils/rundownMetadata'; import { cx } from '../../common/utils/styleUtils'; import ClockTime from '../common/clock-time/ClockTime'; - import { makeSubscriptionsUrl } from './countdown.utils'; import './Countdown.scss'; diff --git a/apps/client/src/views/countdown/CountdownSubscriptions.tsx b/apps/client/src/views/countdown/CountdownSubscriptions.tsx index 724d821e8..408dc3341 100644 --- a/apps/client/src/views/countdown/CountdownSubscriptions.tsx +++ b/apps/client/src/views/countdown/CountdownSubscriptions.tsx @@ -1,13 +1,13 @@ -import { useEffect, useRef, useState } from 'react'; -import { IoPencil } from 'react-icons/io5'; import { MaybeNumber, OntimeEvent } from 'ontime-types'; import { dayInMs } from 'ontime-utils'; +import { useEffect, useRef, useState } from 'react'; +import { IoPencil } from 'react-icons/io5'; import Button from '../../common/components/buttons/Button'; +import useReport from '../../common/hooks-query/useReport'; import { useFadeOutOnInactivity } from '../../common/hooks/useFadeOutOnInactivity'; import useFollowComponent from '../../common/hooks/useFollowComponent'; import { useExpectedStartData, usePlayback, useSelectedEventId } from '../../common/hooks/useSocket'; -import useReport from '../../common/hooks-query/useReport'; import { getOffsetState } from '../../common/utils/offset'; import { ExtendedEntry } from '../../common/utils/rundownMetadata'; import { cx } from '../../common/utils/styleUtils'; @@ -16,7 +16,6 @@ import FollowButton from '../../features/operator/follow-button/FollowButton'; import ClockTime from '../common/clock-time/ClockTime'; import SuperscriptTime from '../common/superscript-time/SuperscriptTime'; import { getPropertyValue } from '../common/viewUtils'; - import { useCountdownOptions } from './countdown.options'; import { CountdownEvent, diff --git a/apps/client/src/views/countdown/SingleEventCountdown.tsx b/apps/client/src/views/countdown/SingleEventCountdown.tsx index c793364ec..d567d3263 100644 --- a/apps/client/src/views/countdown/SingleEventCountdown.tsx +++ b/apps/client/src/views/countdown/SingleEventCountdown.tsx @@ -1,16 +1,15 @@ -import { IoPencil } from 'react-icons/io5'; import { MaybeNumber, OntimeEvent } from 'ontime-types'; import { getExpectedStart } from 'ontime-utils'; +import { IoPencil } from 'react-icons/io5'; import Button from '../../common/components/buttons/Button'; +import useReport from '../../common/hooks-query/useReport'; import { useFadeOutOnInactivity } from '../../common/hooks/useFadeOutOnInactivity'; import { useExpectedStartData } from '../../common/hooks/useSocket'; -import useReport from '../../common/hooks-query/useReport'; import { ExtendedEntry } from '../../common/utils/rundownMetadata'; import { cx } from '../../common/utils/styleUtils'; import SuperscriptTime from '../common/superscript-time/SuperscriptTime'; import { getPropertyValue } from '../common/viewUtils'; - import { useCountdownOptions } from './countdown.options'; import { useSubscriptionDisplayData } from './countdown.utils'; import { ScheduleTime } from './CountdownSubscriptions'; diff --git a/apps/client/src/views/countdown/countdown.options.ts b/apps/client/src/views/countdown/countdown.options.ts index 1ec21d4b0..7f0e12cc7 100644 --- a/apps/client/src/views/countdown/countdown.options.ts +++ b/apps/client/src/views/countdown/countdown.options.ts @@ -1,6 +1,6 @@ +import { CustomFields, EntryId, OntimeEvent } from 'ontime-types'; import { use, useMemo } from 'react'; import { useSearchParams } from 'react-router'; -import { CustomFields, EntryId, OntimeEvent } from 'ontime-types'; import { getTimeOption } from '../../common/components/view-params-editor/common.options'; import { OptionTitle } from '../../common/components/view-params-editor/constants'; diff --git a/apps/client/src/views/countdown/countdown.utils.ts b/apps/client/src/views/countdown/countdown.utils.ts index 2f7895eb1..0ddc68bfe 100644 --- a/apps/client/src/views/countdown/countdown.utils.ts +++ b/apps/client/src/views/countdown/countdown.utils.ts @@ -1,5 +1,5 @@ import { EntryId, MaybeNumber, OffsetMode, OntimeEntry, OntimeEvent, OntimeReport, Playback } from 'ontime-types'; -import { getExpectedStart, MILLIS_PER_MINUTE, millisToString, removeLeadingZero } from 'ontime-utils'; +import { MILLIS_PER_MINUTE, getExpectedStart, millisToString, removeLeadingZero } from 'ontime-utils'; import { useCountdownSocket } from '../../common/hooks/useSocket'; import { ExtendedEntry } from '../../common/utils/rundownMetadata'; diff --git a/apps/client/src/views/countdown/useCountdownData.ts b/apps/client/src/views/countdown/useCountdownData.ts index a9e307bfa..9faaf6c82 100644 --- a/apps/client/src/views/countdown/useCountdownData.ts +++ b/apps/client/src/views/countdown/useCountdownData.ts @@ -6,7 +6,7 @@ import { useFlatRundownWithMetadata } from '../../common/hooks-query/useRundown' import useSettings from '../../common/hooks-query/useSettings'; import { useViewOptionsStore } from '../../common/stores/viewOptions'; import { ExtendedEntry } from '../../common/utils/rundownMetadata'; -import { aggregateQueryStatus, ViewData } from '../utils/viewLoader.utils'; +import { ViewData, aggregateQueryStatus } from '../utils/viewLoader.utils'; export interface CountdownData { customFields: CustomFields; diff --git a/apps/client/src/views/cuesheet/CuesheetPage.module.scss b/apps/client/src/views/cuesheet/CuesheetPage.module.scss index 4c1cf4c32..da4d26a5b 100644 --- a/apps/client/src/views/cuesheet/CuesheetPage.module.scss +++ b/apps/client/src/views/cuesheet/CuesheetPage.module.scss @@ -8,9 +8,9 @@ display: grid; grid-template-rows: 3.5rem auto auto 1fr; grid-template-areas: - 'overview' - 'progress' - 'settings' - 'table'; + 'overview' + 'progress' + 'settings' + 'table'; color: $ui-white; } diff --git a/apps/client/src/views/cuesheet/CuesheetPage.tsx b/apps/client/src/views/cuesheet/CuesheetPage.tsx index cdcf507d1..5fa831731 100644 --- a/apps/client/src/views/cuesheet/CuesheetPage.tsx +++ b/apps/client/src/views/cuesheet/CuesheetPage.tsx @@ -1,5 +1,5 @@ -import { IoApps } from 'react-icons/io5'; import { useDisclosure } from '@mantine/hooks'; +import { IoApps } from 'react-icons/io5'; import IconButton from '../../common/components/buttons/IconButton'; import NavigationMenu from '../../common/components/navigation-menu/NavigationMenu'; @@ -8,7 +8,6 @@ import { useEntryActions } from '../../common/hooks/useEntryAction'; import { useWindowTitle } from '../../common/hooks/useWindowTitle'; import { getIsNavigationLocked } from '../../externals'; import CuesheetOverview from '../../features/overview/CuesheetOverview'; - import EntryEditModal from './cuesheet-edit-modal/EntryEditModal'; import CuesheetProgress from './cuesheet-progress/CuesheetProgress'; import CuesheetTableWrapper from './CuesheetTableWrapper'; diff --git a/apps/client/src/views/cuesheet/CuesheetTableWrapper.tsx b/apps/client/src/views/cuesheet/CuesheetTableWrapper.tsx index f59f06a74..365c9fdf0 100644 --- a/apps/client/src/views/cuesheet/CuesheetTableWrapper.tsx +++ b/apps/client/src/views/cuesheet/CuesheetTableWrapper.tsx @@ -3,7 +3,6 @@ import { memo, use, useMemo } from 'react'; import EmptyPage from '../../common/components/state/EmptyPage'; import { PresetContext } from '../../common/context/PresetContext'; import useCustomFields from '../../common/hooks-query/useCustomFields'; - import CuesheetDnd from './cuesheet-dnd/CuesheetDnd'; import { makeCuesheetColumns } from './cuesheet-table/cuesheet-table-elements/cuesheetColsFactory'; import CuesheetTable from './cuesheet-table/CuesheetTable'; diff --git a/apps/client/src/views/cuesheet/ProtectedCuesheet.tsx b/apps/client/src/views/cuesheet/ProtectedCuesheet.tsx index af8c4aee7..b1fcb5450 100644 --- a/apps/client/src/views/cuesheet/ProtectedCuesheet.tsx +++ b/apps/client/src/views/cuesheet/ProtectedCuesheet.tsx @@ -1,5 +1,4 @@ import ProtectRoute from '../../common/components/protect-route/ProtectRoute'; - import CuesheetPage from './CuesheetPage'; export default function ProtectedCuesheet() { diff --git a/apps/client/src/views/cuesheet/cuesheet-dnd/CuesheetDnd.tsx b/apps/client/src/views/cuesheet/cuesheet-dnd/CuesheetDnd.tsx index bd776877b..6e3734694 100644 --- a/apps/client/src/views/cuesheet/cuesheet-dnd/CuesheetDnd.tsx +++ b/apps/client/src/views/cuesheet/cuesheet-dnd/CuesheetDnd.tsx @@ -1,14 +1,14 @@ -import { PropsWithChildren } from 'react'; import { - closestCorners, DndContext, DragEndEvent, PointerSensor, TouchSensor, + closestCorners, useSensor, useSensors, } from '@dnd-kit/core'; import { ColumnDef } from '@tanstack/react-table'; +import { PropsWithChildren } from 'react'; import type { ExtendedEntry } from '../../../common/utils/rundownMetadata'; import { useColumnOrder } from '../cuesheet-table/useColumnManager'; diff --git a/apps/client/src/views/cuesheet/cuesheet-edit-modal/EntryEditModal.tsx b/apps/client/src/views/cuesheet/cuesheet-edit-modal/EntryEditModal.tsx index 7fc3ec060..c8eb3ccbb 100644 --- a/apps/client/src/views/cuesheet/cuesheet-edit-modal/EntryEditModal.tsx +++ b/apps/client/src/views/cuesheet/cuesheet-edit-modal/EntryEditModal.tsx @@ -2,7 +2,6 @@ import { memo } from 'react'; import Modal from '../../../common/components/modal/Modal'; import CuesheetEntryEditor from '../../../features/rundown/entry-editor/CuesheetEventEditor'; - import { useEditModal } from './useEditModal'; export default memo(EntryEditModal); diff --git a/apps/client/src/views/cuesheet/cuesheet-progress/CuesheetProgress.tsx b/apps/client/src/views/cuesheet/cuesheet-progress/CuesheetProgress.tsx index 8a6eb26fc..d7d084e4a 100644 --- a/apps/client/src/views/cuesheet/cuesheet-progress/CuesheetProgress.tsx +++ b/apps/client/src/views/cuesheet/cuesheet-progress/CuesheetProgress.tsx @@ -1,6 +1,6 @@ import MultiPartProgressBar from '../../../common/components/multi-part-progress-bar/MultiPartProgressBar'; -import { useProgressData } from '../../../common/hooks/useSocket'; import useViewSettings from '../../../common/hooks-query/useViewSettings'; +import { useProgressData } from '../../../common/hooks/useSocket'; import styles from './CuesheetProgress.module.scss'; diff --git a/apps/client/src/views/cuesheet/cuesheet-table/CuesheetTable.tsx b/apps/client/src/views/cuesheet/cuesheet-table/CuesheetTable.tsx index d89024cc7..e5030be90 100644 --- a/apps/client/src/views/cuesheet/cuesheet-table/CuesheetTable.tsx +++ b/apps/client/src/views/cuesheet/cuesheet-table/CuesheetTable.tsx @@ -1,3 +1,6 @@ +import { useTableNav } from '@table-nav/react'; +import { ColumnDef, Table, getCoreRowModel, useReactTable } from '@tanstack/react-table'; +import { OntimeEntry, TimeField, isOntimeDelay, isOntimeGroup, isOntimeMilestone } from 'ontime-types'; import { ComponentProps, memo, useCallback, useEffect, useMemo, useRef } from 'react'; import { ContextProp, @@ -7,22 +10,18 @@ import { TableVirtuoso, TableVirtuosoHandle, } from 'react-virtuoso'; -import { useTableNav } from '@table-nav/react'; -import { ColumnDef, getCoreRowModel, Table, useReactTable } from '@tanstack/react-table'; -import { isOntimeDelay, isOntimeGroup, isOntimeMilestone, OntimeEntry, TimeField } from 'ontime-types'; import EmptyPage from '../../../common/components/state/EmptyPage'; import EmptyTableBody from '../../../common/components/state/EmptyTableBody'; import { useEntryActionsContext } from '../../../common/context/EntryActionsContext'; -import { useSelectedEventId } from '../../../common/hooks/useSocket'; import { useFlatRundownWithMetadata } from '../../../common/hooks-query/useRundown'; +import { useSelectedEventId } from '../../../common/hooks/useSocket'; import type { ExtendedEntry } from '../../../common/utils/rundownMetadata'; -import { usePersistedRundownOptions } from '../../../features/rundown/rundown.options'; import EditorTableSettings from '../../../features/rundown/rundown-table/EditorTableSettings'; +import { usePersistedRundownOptions } from '../../../features/rundown/rundown.options'; import { useEventSelection } from '../../../features/rundown/useEventSelection'; import { AppMode } from '../../../ontimeConfig'; import { usePersistedCuesheetOptions } from '../cuesheet.options'; - import { CuesheetHeader, SortableCuesheetHeader } from './cuesheet-table-elements/CuesheetHeader'; import DelayRow from './cuesheet-table-elements/DelayRow'; import EventRow from './cuesheet-table-elements/EventRow'; @@ -252,7 +251,6 @@ export default function CuesheetTable({ columns, cuesheetMode, tableRoot, setCue ); } - interface CuesheetVirtuosoContext { columnSizeVars: { [key: string]: number }; cursor: string | null; diff --git a/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/CuesheetHeader.tsx b/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/CuesheetHeader.tsx index 634a5180b..0704133fb 100644 --- a/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/CuesheetHeader.tsx +++ b/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/CuesheetHeader.tsx @@ -1,12 +1,11 @@ +import { SortableContext, horizontalListSortingStrategy } from '@dnd-kit/sortable'; +import { HeaderGroup, flexRender } from '@tanstack/react-table'; import { CSSProperties } from 'react'; -import { horizontalListSortingStrategy, SortableContext } from '@dnd-kit/sortable'; -import { flexRender, HeaderGroup } from '@tanstack/react-table'; import type { ExtendedEntry } from '../../../../common/utils/rundownMetadata'; import { getAccessibleColour } from '../../../../common/utils/styleUtils'; import { AppMode } from '../../../../ontimeConfig'; import { usePersistedCuesheetOptions } from '../../cuesheet.options'; - import { Draggable, SortableCell, TableCell } from './SortableCell'; import style from '../CuesheetTable.module.scss'; diff --git a/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/DurationInput.tsx b/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/DurationInput.tsx index 74a28edad..4882da9d3 100644 --- a/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/DurationInput.tsx +++ b/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/DurationInput.tsx @@ -1,5 +1,5 @@ -import { memo, PropsWithChildren, useCallback, useEffect, useRef, useState } from 'react'; import { millisToString, parseUserTime } from 'ontime-utils'; +import { PropsWithChildren, memo, useCallback, useEffect, useRef, useState } from 'react'; import SingleLineCell from './SingleLineCell'; import TextLikeInput from './TextLikeInput'; 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 a6e9a5585..2b088b8ab 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 @@ -1,8 +1,8 @@ -import { CSSProperties, useMemo } from 'react'; -import { IoEllipsisHorizontal } from 'react-icons/io5'; -import { flexRender, Table } from '@tanstack/react-table'; +import { Table, flexRender } from '@tanstack/react-table'; import { EntryId, OntimeEntry, RGBColour, SupportedEntry } from 'ontime-types'; import { colourToHex, cssOrHexToColour } from 'ontime-utils'; +import { CSSProperties, useMemo } from 'react'; +import { IoEllipsisHorizontal } from 'react-icons/io5'; import IconButton from '../../../../common/components/buttons/IconButton'; import type { ExtendedEntry } from '../../../../common/utils/rundownMetadata'; diff --git a/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/GroupRow.tsx b/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/GroupRow.tsx index c08707def..e6281dbeb 100644 --- a/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/GroupRow.tsx +++ b/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/GroupRow.tsx @@ -1,7 +1,7 @@ +import { Table, flexRender } from '@tanstack/react-table'; +import { EntryId, SupportedEntry } from 'ontime-types'; import { CSSProperties } from 'react'; import { IoEllipsisHorizontal } from 'react-icons/io5'; -import { flexRender, Table } from '@tanstack/react-table'; -import { EntryId, SupportedEntry } from 'ontime-types'; import IconButton from '../../../../common/components/buttons/IconButton'; import type { ExtendedEntry } from '../../../../common/utils/rundownMetadata'; diff --git a/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/MilestoneRow.tsx b/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/MilestoneRow.tsx index 7955d43ec..d9f7e0358 100644 --- a/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/MilestoneRow.tsx +++ b/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/MilestoneRow.tsx @@ -1,8 +1,8 @@ -import { CSSProperties } from 'react'; -import { IoEllipsisHorizontal } from 'react-icons/io5'; -import { flexRender, Table } from '@tanstack/react-table'; +import { Table, flexRender } from '@tanstack/react-table'; import { EntryId, SupportedEntry } from 'ontime-types'; import { colourToHex, cssOrHexToColour } from 'ontime-utils'; +import { CSSProperties } from 'react'; +import { IoEllipsisHorizontal } from 'react-icons/io5'; import IconButton from '../../../../common/components/buttons/IconButton'; import type { ExtendedEntry } from '../../../../common/utils/rundownMetadata'; diff --git a/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/SortableCell.tsx b/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/SortableCell.tsx index 7c7226c76..b43c2d9ce 100644 --- a/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/SortableCell.tsx +++ b/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/SortableCell.tsx @@ -1,7 +1,7 @@ -import { CSSProperties, ReactNode } from 'react'; import { useSortable } from '@dnd-kit/sortable'; import { CSS } from '@dnd-kit/utilities'; import { Header } from '@tanstack/react-table'; +import { CSSProperties, ReactNode } from 'react'; import type { ExtendedEntry } from '../../../../common/utils/rundownMetadata'; diff --git a/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/TextLikeInput.tsx b/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/TextLikeInput.tsx index 51047ca2a..5a185e373 100644 --- a/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/TextLikeInput.tsx +++ b/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/TextLikeInput.tsx @@ -1,4 +1,4 @@ -import { forwardRef, HTMLAttributes, memo, PropsWithChildren, useImperativeHandle, useRef } from 'react'; +import { HTMLAttributes, PropsWithChildren, forwardRef, memo, useImperativeHandle, useRef } from 'react'; import { cx } from '../../../../common/utils/styleUtils'; diff --git a/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/TimeInput.tsx b/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/TimeInput.tsx index 8e7f9d132..29e03f898 100644 --- a/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/TimeInput.tsx +++ b/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/TimeInput.tsx @@ -1,8 +1,7 @@ -import { memo, PropsWithChildren, useCallback, useEffect, useRef, useState } from 'react'; import { parseUserTime } from 'ontime-utils'; +import { PropsWithChildren, memo, useCallback, useEffect, useRef, useState } from 'react'; import { formatTime } from '../../../../common/utils/time'; - import SingleLineCell from './SingleLineCell'; import TextLikeInput from './TextLikeInput'; diff --git a/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/cuesheetColsFactory.tsx b/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/cuesheetColsFactory.tsx index 7724629c1..e143ee2f7 100644 --- a/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/cuesheetColsFactory.tsx +++ b/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/cuesheetColsFactory.tsx @@ -1,14 +1,13 @@ -import { useCallback } from 'react'; import { CellContext, ColumnDef } from '@tanstack/react-table'; -import { CustomFields, isOntimeDelay, isOntimeEvent, TimeStrategy, URLPreset } from 'ontime-types'; +import { CustomFields, TimeStrategy, URLPreset, isOntimeDelay, isOntimeEvent } from 'ontime-types'; import { millisToString } from 'ontime-utils'; +import { useCallback } from 'react'; import DelayIndicator from '../../../../common/components/delay-indicator/DelayIndicator'; import type { ExtendedEntry } from '../../../../common/utils/rundownMetadata'; import { formatDuration, formatTime } from '../../../../common/utils/time'; import { AppMode } from '../../../../ontimeConfig'; import { getCuesheetColumnAccessPolicy } from '../../cuesheet.policies'; - import DurationInput from './DurationInput'; import EditableImage from './EditableImage'; import FlagCell from './FlagCell'; diff --git a/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-menu/TableMenu.tsx b/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-menu/TableMenu.tsx index a29366a79..cd4b2a0df 100644 --- a/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-menu/TableMenu.tsx +++ b/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-menu/TableMenu.tsx @@ -1,12 +1,11 @@ +import { SupportedEntry } from 'ontime-types'; import { memo } from 'react'; import { IoAdd, IoArrowDown, IoArrowUp, IoDuplicateOutline, IoOptions, IoTrash } from 'react-icons/io5'; -import { SupportedEntry } from 'ontime-types'; import { PositionedDropdownMenu } from '../../../../common/components/dropdown-menu/DropdownMenu'; import { useEntryActionsContext } from '../../../../common/context/EntryActionsContext'; import { useEditModal } from '../../cuesheet-edit-modal/useEditModal'; import { useCuesheetPermissions } from '../../useTablePermissions'; - import { useCuesheetTableMenu } from './useCuesheetTableMenu'; export default memo(TableMenu); diff --git a/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-settings/CuesheetTableSettings.tsx b/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-settings/CuesheetTableSettings.tsx index 02c6c17c3..dac44e2f9 100644 --- a/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-settings/CuesheetTableSettings.tsx +++ b/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-settings/CuesheetTableSettings.tsx @@ -1,10 +1,10 @@ -import { ReactNode } from 'react'; -import { IoBookOutline, IoChevronDown, IoOptions } from 'react-icons/io5'; import { Popover } from '@base-ui/react/popover'; import { Toggle } from '@base-ui/react/toggle'; import { ToggleGroup } from '@base-ui/react/toggle-group'; import { Toolbar } from '@base-ui/react/toolbar'; import type { Column } from '@tanstack/react-table'; +import { ReactNode } from 'react'; +import { IoBookOutline, IoChevronDown, IoOptions } from 'react-icons/io5'; import Button from '../../../../common/components/buttons/Button'; import Checkbox from '../../../../common/components/checkbox/Checkbox'; @@ -15,7 +15,6 @@ import { cx } from '../../../../common/utils/styleUtils'; import { AppMode } from '../../../../ontimeConfig'; import { CuesheetOptions, usePersistedCuesheetOptions } from '../../cuesheet.options'; import { useCuesheetPermissions } from '../../useTablePermissions'; - import CuesheetShareModal from './CuesheetShareModal'; import style from './CuesheetTableSettings.module.scss'; diff --git a/apps/client/src/views/cuesheet/cuesheet-table/useColumnManager.tsx b/apps/client/src/views/cuesheet/cuesheet-table/useColumnManager.tsx index 6ca24ac18..752eb824d 100644 --- a/apps/client/src/views/cuesheet/cuesheet-table/useColumnManager.tsx +++ b/apps/client/src/views/cuesheet/cuesheet-table/useColumnManager.tsx @@ -1,6 +1,6 @@ -import { useCallback, useEffect, useMemo, useState } from 'react'; import { useLocalStorage } from '@mantine/hooks'; import { ColumnDef, ColumnSizingState, Updater } from '@tanstack/react-table'; +import { useCallback, useEffect, useMemo, useState } from 'react'; import { debounce } from '../../../common/utils/debounce'; import { makeStageKey } from '../../../common/utils/localStorage'; diff --git a/apps/client/src/views/cuesheet/cuesheet.policies.ts b/apps/client/src/views/cuesheet/cuesheet.policies.ts index a36de6a76..be758323b 100644 --- a/apps/client/src/views/cuesheet/cuesheet.policies.ts +++ b/apps/client/src/views/cuesheet/cuesheet.policies.ts @@ -1,7 +1,6 @@ import { URLPreset } from 'ontime-types'; import { AppMode } from '../../ontimeConfig'; - import type { CuesheetPermissions } from './useTablePermissions'; function getPermissionKeys(permission: string | undefined): Set { diff --git a/apps/client/src/views/cuesheet/useApplyCuesheetPolicy.ts b/apps/client/src/views/cuesheet/useApplyCuesheetPolicy.ts index 71b2b3c91..6d5db7376 100644 --- a/apps/client/src/views/cuesheet/useApplyCuesheetPolicy.ts +++ b/apps/client/src/views/cuesheet/useApplyCuesheetPolicy.ts @@ -1,10 +1,9 @@ -import { useCallback, useEffect, useMemo } from 'react'; import { useSessionStorage } from '@mantine/hooks'; import { URLPreset } from 'ontime-types'; +import { useCallback, useEffect, useMemo } from 'react'; import { sessionScope } from '../../externals'; import { AppMode, sessionKeys } from '../../ontimeConfig'; - import { getCuesheetPermissionsPolicy } from './cuesheet.policies'; import { useCuesheetPermissions } from './useTablePermissions'; diff --git a/apps/client/src/views/editor/Editor.tsx b/apps/client/src/views/editor/Editor.tsx index 49e83c3a7..66d848c65 100644 --- a/apps/client/src/views/editor/Editor.tsx +++ b/apps/client/src/views/editor/Editor.tsx @@ -2,7 +2,6 @@ import { lazy } from 'react'; import TrackingPlaybackBar from '../../features/control/playback/tracking-playback-bar/TrackingPlaybackBar'; import { AppMode } from '../../ontimeConfig'; - import TitleList from './title-list/TitleList'; import { EditorLayoutMode, useEditorLayout } from './useEditorLayout'; diff --git a/apps/client/src/views/editor/EditorLayoutOptions.tsx b/apps/client/src/views/editor/EditorLayoutOptions.tsx index f100f132b..44425002b 100644 --- a/apps/client/src/views/editor/EditorLayoutOptions.tsx +++ b/apps/client/src/views/editor/EditorLayoutOptions.tsx @@ -4,7 +4,6 @@ import { LuLayoutDashboard } from 'react-icons/lu'; import IconButton from '../../common/components/buttons/IconButton'; import { DropdownMenu, DropdownMenuOption } from '../../common/components/dropdown-menu/DropdownMenu'; - import { EditorLayoutMode, useEditorLayout } from './useEditorLayout'; export default memo(EditorLayoutOptions); diff --git a/apps/client/src/views/editor/ProtectedEditor.tsx b/apps/client/src/views/editor/ProtectedEditor.tsx index 4f0c725b4..5fa64029c 100644 --- a/apps/client/src/views/editor/ProtectedEditor.tsx +++ b/apps/client/src/views/editor/ProtectedEditor.tsx @@ -1,6 +1,6 @@ +import { useDisclosure, useHotkeys } from '@mantine/hooks'; import { useCallback, useEffect } from 'react'; import { IoApps, IoClose, IoSettingsOutline } from 'react-icons/io5'; -import { useDisclosure, useHotkeys } from '@mantine/hooks'; import IconButton from '../../common/components/buttons/IconButton'; import NavigationMenu from '../../common/components/navigation-menu/NavigationMenu'; @@ -10,10 +10,9 @@ import { useWindowTitle } from '../../common/hooks/useWindowTitle'; import AppSettings from '../../features/app-settings/AppSettings'; import useAppSettingsNavigation from '../../features/app-settings/useAppSettingsNavigation'; import EditorOverview from '../../features/overview/EditorOverview'; - -import WelcomePlacement from './welcome/WelcomePlacement'; import Editor from './Editor'; import EditorLayoutOptions from './EditorLayoutOptions'; +import WelcomePlacement from './welcome/WelcomePlacement'; import styles from './ProtectedEditor.module.scss'; diff --git a/apps/client/src/views/editor/finder/Finder.module.scss b/apps/client/src/views/editor/finder/Finder.module.scss index 9b7032bd2..d1b28e3b1 100644 --- a/apps/client/src/views/editor/finder/Finder.module.scss +++ b/apps/client/src/views/editor/finder/Finder.module.scss @@ -67,4 +67,4 @@ max-height: 70vh; overflow: auto; padding-top: 1rem; -} \ No newline at end of file +} diff --git a/apps/client/src/views/editor/finder/Finder.tsx b/apps/client/src/views/editor/finder/Finder.tsx index 65244945b..3a04ff89c 100644 --- a/apps/client/src/views/editor/finder/Finder.tsx +++ b/apps/client/src/views/editor/finder/Finder.tsx @@ -1,10 +1,9 @@ -import { KeyboardEvent, useState } from 'react'; import { useDebouncedCallback } from '@mantine/hooks'; import { SupportedEntry } from 'ontime-types'; +import { KeyboardEvent, useState } from 'react'; import Input from '../../../common/components/input/input/Input'; import Modal from '../../../common/components/modal/Modal'; - import useFinder from './useFinder'; import style from './Finder.module.scss'; diff --git a/apps/client/src/views/editor/finder/useFinder.tsx b/apps/client/src/views/editor/finder/useFinder.tsx index 58fbb7559..fdfda8a2f 100644 --- a/apps/client/src/views/editor/finder/useFinder.tsx +++ b/apps/client/src/views/editor/finder/useFinder.tsx @@ -1,5 +1,5 @@ +import { EntryId, MaybeString, SupportedEntry, isOntimeEvent, isOntimeGroup, isOntimeMilestone } from 'ontime-types'; import { ChangeEvent, useCallback, useEffect, useRef, useState } from 'react'; -import { EntryId, isOntimeEvent, isOntimeGroup, isOntimeMilestone, MaybeString, SupportedEntry } from 'ontime-types'; import { useFlatRundown } from '../../../common/hooks-query/useRundown'; import { useSelectAndRevealEntry } from '../../../features/rundown/useSelectAndRevealEntry'; diff --git a/apps/client/src/views/editor/pip-timer/PipHost.tsx b/apps/client/src/views/editor/pip-timer/PipHost.tsx index 18e332ecd..a11e914ef 100644 --- a/apps/client/src/views/editor/pip-timer/PipHost.tsx +++ b/apps/client/src/views/editor/pip-timer/PipHost.tsx @@ -1,9 +1,8 @@ -import { createRoot } from 'react-dom/client'; import { ErrorBoundary } from '@sentry/react'; +import { createRoot } from 'react-dom/client'; import { CornerPipButton } from '../../../common/components/editor-utils/EditorUtils'; import useViewSettings from '../../../common/hooks-query/useViewSettings'; - import { PipTimer } from './PipTimer'; export default function PipTimerHost() { diff --git a/apps/client/src/views/editor/pip-timer/PipRoot.tsx b/apps/client/src/views/editor/pip-timer/PipRoot.tsx index 7c3b7ce70..1ce8f4a4b 100644 --- a/apps/client/src/views/editor/pip-timer/PipRoot.tsx +++ b/apps/client/src/views/editor/pip-timer/PipRoot.tsx @@ -1,4 +1,4 @@ -import { lazy, memo, Suspense } from 'react'; +import { Suspense, lazy, memo } from 'react'; import { isPipSupported } from './pip.utils'; diff --git a/apps/client/src/views/editor/pip-timer/PipTimer.scss b/apps/client/src/views/editor/pip-timer/PipTimer.scss index b75f7731a..44d3a1c52 100644 --- a/apps/client/src/views/editor/pip-timer/PipTimer.scss +++ b/apps/client/src/views/editor/pip-timer/PipTimer.scss @@ -111,7 +111,7 @@ position: fixed; inset: 0; padding: 2vw; - background: $viewer-background-color; + background: $viewer-background-color; opacity: 0; transition: opacity $viewer-transition-time; diff --git a/apps/client/src/views/editor/title-list/TitleList.tsx b/apps/client/src/views/editor/title-list/TitleList.tsx index 635c96427..1082a8677 100644 --- a/apps/client/src/views/editor/title-list/TitleList.tsx +++ b/apps/client/src/views/editor/title-list/TitleList.tsx @@ -1,15 +1,14 @@ +import { OntimeEvent, isOntimeEvent } from 'ontime-types'; import { useCallback, useEffect, useMemo, useRef } from 'react'; import { Virtuoso, VirtuosoHandle } from 'react-virtuoso'; -import { isOntimeEvent, OntimeEvent } from 'ontime-types'; import ScrollArea from '../../../common/components/scroll-area/ScrollArea'; -import { useSelectedEventId } from '../../../common/hooks/useSocket'; import useRundown from '../../../common/hooks-query/useRundown'; +import { useSelectedEventId } from '../../../common/hooks/useSocket'; import { ExtendedEntry, getFlatRundownMetadata } from '../../../common/utils/rundownMetadata'; import { useEventSelection } from '../../../features/rundown/useEventSelection'; import { useSelectAndRevealEntry } from '../../../features/rundown/useSelectAndRevealEntry'; import { AppMode } from '../../../ontimeConfig'; - import { getCurrentEventInfo } from './titleList.utils'; import TitleListEmpty from './TitleListEmpty'; import TitleListItem from './TitleListItem'; diff --git a/apps/client/src/views/editor/title-list/TitleListItem.tsx b/apps/client/src/views/editor/title-list/TitleListItem.tsx index 199f413d0..36c6f6edb 100644 --- a/apps/client/src/views/editor/title-list/TitleListItem.tsx +++ b/apps/client/src/views/editor/title-list/TitleListItem.tsx @@ -1,6 +1,6 @@ -import { memo, useCallback } from 'react'; import { Day, OntimeEvent } from 'ontime-types'; import { MILLIS_PER_MINUTE, MILLIS_PER_SECOND } from 'ontime-utils'; +import { memo, useCallback } from 'react'; import Tooltip from '../../../common/components/tooltip/Tooltip'; import { ExtendedEntry } from '../../../common/utils/rundownMetadata'; diff --git a/apps/client/src/views/editor/useEditorLayout.ts b/apps/client/src/views/editor/useEditorLayout.ts index a4b3d5fa6..454ae7326 100644 --- a/apps/client/src/views/editor/useEditorLayout.ts +++ b/apps/client/src/views/editor/useEditorLayout.ts @@ -1,5 +1,5 @@ -import { useSearchParams } from 'react-router'; import { isValueOfEnum } from 'ontime-utils'; +import { useSearchParams } from 'react-router'; const layoutParam = 'layout'; diff --git a/apps/client/src/views/editor/welcome/Welcome.tsx b/apps/client/src/views/editor/welcome/Welcome.tsx index 726a25440..675b31d43 100644 --- a/apps/client/src/views/editor/welcome/Welcome.tsx +++ b/apps/client/src/views/editor/welcome/Welcome.tsx @@ -11,7 +11,6 @@ import * as Editor from '../../../common/components/editor-utils/EditorUtils'; import ExternalLink from '../../../common/components/link/external-link/ExternalLink'; import Modal from '../../../common/components/modal/Modal'; import { appVersion, discordUrl, documentationUrl, websiteUrl } from '../../../externals'; - import ImportProjectButton from './composite/ImportProjectButton'; import WelcomeProjectList from './composite/WelcomeProjectList'; diff --git a/apps/client/src/views/editor/welcome/WelcomePlacement.tsx b/apps/client/src/views/editor/welcome/WelcomePlacement.tsx index 2ab0fb593..587fbe020 100644 --- a/apps/client/src/views/editor/welcome/WelcomePlacement.tsx +++ b/apps/client/src/views/editor/welcome/WelcomePlacement.tsx @@ -1,5 +1,4 @@ import { useDialogStore } from '../../../common/stores/dialogStore'; - import Welcome from './Welcome'; export default function WelcomePlacement() { diff --git a/apps/client/src/views/project-info/ProjectInfo.scss b/apps/client/src/views/project-info/ProjectInfo.scss index 77f8ce0a2..6c3fcc491 100644 --- a/apps/client/src/views/project-info/ProjectInfo.scss +++ b/apps/client/src/views/project-info/ProjectInfo.scss @@ -27,7 +27,7 @@ overflow-y: auto; width: min(calc(100vw - 4rem), 960px); display: flex; - flex-direction: column; + flex-direction: column; align-items: start; gap: $view-element-gap; diff --git a/apps/client/src/views/project-info/ProjectInfo.tsx b/apps/client/src/views/project-info/ProjectInfo.tsx index 0ceab40c6..bae7d896a 100644 --- a/apps/client/src/views/project-info/ProjectInfo.tsx +++ b/apps/client/src/views/project-info/ProjectInfo.tsx @@ -1,5 +1,5 @@ -import { IoOpenOutline } from 'react-icons/io5'; import { OntimeView } from 'ontime-types'; +import { IoOpenOutline } from 'react-icons/io5'; import EmptyPage from '../../common/components/state/EmptyPage'; import ViewLogo from '../../common/components/view-logo/ViewLogo'; @@ -7,7 +7,6 @@ import ViewParamsEditor from '../../common/components/view-params-editor/ViewPar import { useWindowTitle } from '../../common/hooks/useWindowTitle'; import { useTranslation } from '../../translation/TranslationProvider'; import Loader from '../common/loader/Loader'; - import { ProjectInfoData, useProjectInfoData } from './useProjectInfoData'; import './ProjectInfo.scss'; diff --git a/apps/client/src/views/studio/Studio.tsx b/apps/client/src/views/studio/Studio.tsx index fd0e8a033..e363dc7b8 100644 --- a/apps/client/src/views/studio/Studio.tsx +++ b/apps/client/src/views/studio/Studio.tsx @@ -1,5 +1,5 @@ -import { useMemo } from 'react'; import { OntimeView } from 'ontime-types'; +import { useMemo } from 'react'; import EmptyPage from '../../common/components/state/EmptyPage'; import ViewLogo from '../../common/components/view-logo/ViewLogo'; @@ -8,7 +8,6 @@ import { useWindowTitle } from '../../common/hooks/useWindowTitle'; import { cx } from '../../common/utils/styleUtils'; import { getDefaultFormat } from '../../common/utils/time'; import Loader from '../common/loader/Loader'; - import { getStudioOptions, useStudioOptions } from './studio.options'; import StudioClock from './StudioClock'; import StudioTimers from './StudioTimers'; diff --git a/apps/client/src/views/studio/StudioClock.tsx b/apps/client/src/views/studio/StudioClock.tsx index 1e2d7e3b9..01bfcd8c9 100644 --- a/apps/client/src/views/studio/StudioClock.tsx +++ b/apps/client/src/views/studio/StudioClock.tsx @@ -5,7 +5,6 @@ import { useStudioClockSocket } from '../../common/hooks/useSocket'; import { cx } from '../../common/utils/styleUtils'; import { formatTime } from '../../common/utils/time'; import SuperscriptTime from '../common/superscript-time/SuperscriptTime'; - import { getLargeClockData } from './studioClock.utils'; import './StudioClock.scss'; diff --git a/apps/client/src/views/studio/StudioTimers.tsx b/apps/client/src/views/studio/StudioTimers.tsx index a47f8d467..15d1bd069 100644 --- a/apps/client/src/views/studio/StudioTimers.tsx +++ b/apps/client/src/views/studio/StudioTimers.tsx @@ -7,7 +7,6 @@ import { cx } from '../../common/utils/styleUtils'; import { useTranslation } from '../../translation/TranslationProvider'; import { getPropertyValue } from '../common/viewUtils'; import { getTimerColour } from '../utils/presentation.utils'; - import { useStudioOptions } from './studio.options'; import { getFormattedEventData, getFormattedScheduleTimes } from './studioTimers.utils'; diff --git a/apps/client/src/views/studio/studio.options.ts b/apps/client/src/views/studio/studio.options.ts index 5d39d2e0f..f13075d92 100644 --- a/apps/client/src/views/studio/studio.options.ts +++ b/apps/client/src/views/studio/studio.options.ts @@ -1,6 +1,6 @@ +import { CustomFields, OntimeEvent } from 'ontime-types'; import { use, useMemo } from 'react'; import { useSearchParams } from 'react-router'; -import { CustomFields, OntimeEvent } from 'ontime-types'; import { getTimeOption } from '../../common/components/view-params-editor/common.options'; import { OptionTitle } from '../../common/components/view-params-editor/constants'; diff --git a/apps/client/src/views/studio/useStudioData.ts b/apps/client/src/views/studio/useStudioData.ts index 94a84d280..d4867b844 100644 --- a/apps/client/src/views/studio/useStudioData.ts +++ b/apps/client/src/views/studio/useStudioData.ts @@ -5,7 +5,7 @@ import useProjectData from '../../common/hooks-query/useProjectData'; import useSettings from '../../common/hooks-query/useSettings'; import useViewSettings from '../../common/hooks-query/useViewSettings'; import { useViewOptionsStore } from '../../common/stores/viewOptions'; -import { aggregateQueryStatus, ViewData } from '../utils/viewLoader.utils'; +import { ViewData, aggregateQueryStatus } from '../utils/viewLoader.utils'; export interface StudioData { customFields: CustomFields; diff --git a/apps/client/src/views/timeline/Timeline.tsx b/apps/client/src/views/timeline/Timeline.tsx index 3bdbe8aa3..8a07ac377 100644 --- a/apps/client/src/views/timeline/Timeline.tsx +++ b/apps/client/src/views/timeline/Timeline.tsx @@ -1,13 +1,12 @@ -import { memo, useMemo, useRef } from 'react'; import { useViewportSize } from '@mantine/hooks'; -import { isOntimeEvent, isPlayableEvent, OntimeEntry, PlayableEvent } from 'ontime-types'; -import { dayInMs, getLastEvent, MILLIS_PER_HOUR } from 'ontime-utils'; +import { OntimeEntry, PlayableEvent, isOntimeEvent, isPlayableEvent } from 'ontime-types'; +import { MILLIS_PER_HOUR, dayInMs, getLastEvent } from 'ontime-utils'; +import { memo, useMemo, useRef } from 'react'; import useHorizontalFollowComponent from '../../common/hooks/useHorizontalFollowComponent'; import { ExtendedEntry } from '../../common/utils/rundownMetadata'; import { cx } from '../../common/utils/styleUtils'; import { getPropertyValue } from '../common/viewUtils'; - import TimelineMarkers from './timeline-markers/TimelineMarkers'; import { useTimelineOptions } from './timeline.options'; import { calculateTimelineLayout, getEndHour, getStartHour } from './timeline.utils'; diff --git a/apps/client/src/views/timeline/TimelineEntry.tsx b/apps/client/src/views/timeline/TimelineEntry.tsx index 2b9e2dd4b..86492f3b0 100644 --- a/apps/client/src/views/timeline/TimelineEntry.tsx +++ b/apps/client/src/views/timeline/TimelineEntry.tsx @@ -1,12 +1,11 @@ -import { RefObject } from 'react'; import { Day } from 'ontime-types'; +import { CSSProperties, RefObject } from 'react'; import { useExpectedStartData, useTimer } from '../../common/hooks/useSocket'; import { getProgress } from '../../common/utils/getProgress'; import { alpha, cx } from '../../common/utils/styleUtils'; import { formatDuration, formatTime, getExpectedTimesFromExtendedEvent } from '../../common/utils/time'; import { useTranslation } from '../../translation/TranslationProvider'; - import { getStatusLabel } from './timeline.utils'; import style from './Timeline.module.scss'; @@ -64,21 +63,25 @@ export function TimelineEntry({
{status === 'live' ? :
}
{formattedStartTime}
@@ -160,5 +163,7 @@ function TimelineEntryStatus({ function ActiveBlock() { const { current, duration } = useTimer(); const progress = getProgress(current, duration); - return
; + return ( +
+ ); } diff --git a/apps/client/src/views/timeline/TimelinePage.tsx b/apps/client/src/views/timeline/TimelinePage.tsx index 6d2677c74..a4cd0be45 100644 --- a/apps/client/src/views/timeline/TimelinePage.tsx +++ b/apps/client/src/views/timeline/TimelinePage.tsx @@ -1,5 +1,5 @@ -import { useMemo } from 'react'; import { OntimeView } from 'ontime-types'; +import { useMemo } from 'react'; import EmptyPage from '../../common/components/state/EmptyPage'; import ViewLogo from '../../common/components/view-logo/ViewLogo'; @@ -10,7 +10,6 @@ import { formatTime, getDefaultFormat } from '../../common/utils/time'; import { useTranslation } from '../../translation/TranslationProvider'; import Loader from '../common/loader/Loader'; import SuperscriptTime from '../common/superscript-time/SuperscriptTime'; - import Timeline from './Timeline'; import { getTimelineOptions, useTimelineOptions } from './timeline.options'; import { getUpcomingEvents, useScopedRundown } from './timeline.utils'; diff --git a/apps/client/src/views/timeline/TimelineSections.tsx b/apps/client/src/views/timeline/TimelineSections.tsx index c0ebe7b8b..e94219f42 100644 --- a/apps/client/src/views/timeline/TimelineSections.tsx +++ b/apps/client/src/views/timeline/TimelineSections.tsx @@ -6,7 +6,6 @@ import { ExtendedEntry } from '../../common/utils/rundownMetadata'; import { formatDuration, getExpectedTimesFromExtendedEvent } from '../../common/utils/time'; import { useTranslation } from '../../translation/TranslationProvider'; import { getPropertyValue } from '../common/viewUtils'; - import TimelineSection from './timeline-section/TimelineSection'; interface TimelineSectionsProps { diff --git a/apps/client/src/views/timeline/timeline-section/TimelineSection.tsx b/apps/client/src/views/timeline/timeline-section/TimelineSection.tsx index 2eb2ebe25..c37ca3cd3 100644 --- a/apps/client/src/views/timeline/timeline-section/TimelineSection.tsx +++ b/apps/client/src/views/timeline/timeline-section/TimelineSection.tsx @@ -1,5 +1,5 @@ -import { memo } from 'react'; import { MaybeString } from 'ontime-types'; +import { memo } from 'react'; import { cx } from '../../../common/utils/styleUtils'; diff --git a/apps/client/src/views/timeline/timeline.options.ts b/apps/client/src/views/timeline/timeline.options.ts index 540f7c611..23c5cbfa3 100644 --- a/apps/client/src/views/timeline/timeline.options.ts +++ b/apps/client/src/views/timeline/timeline.options.ts @@ -1,6 +1,6 @@ +import { CustomFields, OntimeEvent } from 'ontime-types'; import { use, useMemo } from 'react'; import { useSearchParams } from 'react-router'; -import { CustomFields, OntimeEvent } from 'ontime-types'; import { getTimeOption } from '../../common/components/view-params-editor/common.options'; import { OptionTitle } from '../../common/components/view-params-editor/constants'; diff --git a/apps/client/src/views/timeline/timeline.utils.ts b/apps/client/src/views/timeline/timeline.utils.ts index ab4cd85dc..f578f5d0b 100644 --- a/apps/client/src/views/timeline/timeline.utils.ts +++ b/apps/client/src/views/timeline/timeline.utils.ts @@ -1,19 +1,18 @@ -import { useMemo } from 'react'; -import { isOntimeEvent, isPlayableEvent, MaybeString, OntimeEntry, OntimeEvent, PlayableEvent } from 'ontime-types'; +import { MaybeString, OntimeEntry, OntimeEvent, PlayableEvent, isOntimeEvent, isPlayableEvent } from 'ontime-types'; import { + MILLIS_PER_HOUR, + MILLIS_PER_MINUTE, dayInMs, getEventWithId, getFirstEvent, getNextEvent, getTimeFrom, isNewLatest, - MILLIS_PER_HOUR, - MILLIS_PER_MINUTE, } from 'ontime-utils'; +import { useMemo } from 'react'; import { ExtendedEntry } from '../../common/utils/rundownMetadata'; import { formatDuration } from '../../common/utils/time'; - import { useTimelineOptions } from './timeline.options'; import type { ProgressStatus } from './TimelineEntry'; diff --git a/apps/client/src/views/timeline/useTimelineData.ts b/apps/client/src/views/timeline/useTimelineData.ts index 74675d3d4..bd2f996f6 100644 --- a/apps/client/src/views/timeline/useTimelineData.ts +++ b/apps/client/src/views/timeline/useTimelineData.ts @@ -5,7 +5,7 @@ import useProjectData from '../../common/hooks-query/useProjectData'; import { useFlatRundownWithMetadata } from '../../common/hooks-query/useRundown'; import useSettings from '../../common/hooks-query/useSettings'; import { ExtendedEntry } from '../../common/utils/rundownMetadata'; -import { aggregateQueryStatus, ViewData } from '../utils/viewLoader.utils'; +import { ViewData, aggregateQueryStatus } from '../utils/viewLoader.utils'; export interface TimelineData { events: ExtendedEntry[]; diff --git a/apps/client/src/views/timer/Timer.tsx b/apps/client/src/views/timer/Timer.tsx index 01e5c5883..a36e1a990 100644 --- a/apps/client/src/views/timer/Timer.tsx +++ b/apps/client/src/views/timer/Timer.tsx @@ -1,5 +1,5 @@ -import { useMemo } from 'react'; import { OntimeView, TimerType } from 'ontime-types'; +import { useMemo } from 'react'; import { FitText } from '../../common/components/fit-text/FitText'; import MultiPartProgressBar from '../../common/components/multi-part-progress-bar/MultiPartProgressBar'; @@ -16,7 +16,6 @@ import Loader from '../common/loader/Loader'; import SuperscriptTime from '../common/superscript-time/SuperscriptTime'; import { getFormattedTimer, getTimerByType } from '../common/viewUtils'; import { getTimerColour } from '../utils/presentation.utils'; - import { getTimerOptions, useTimerOptions } from './timer.options'; import { getCardData, diff --git a/apps/client/src/views/timer/timer.options.ts b/apps/client/src/views/timer/timer.options.ts index e939e3e5f..9533d8852 100644 --- a/apps/client/src/views/timer/timer.options.ts +++ b/apps/client/src/views/timer/timer.options.ts @@ -1,7 +1,7 @@ -import { use, useMemo } from 'react'; -import { useSearchParams } from 'react-router'; import { CustomFields, OntimeEvent, TimerType } from 'ontime-types'; import { validateTimerType } from 'ontime-utils'; +import { use, useMemo } from 'react'; +import { useSearchParams } from 'react-router'; import type { SelectOption } from '../../common/components/select/Select'; import { diff --git a/apps/client/src/views/timer/useTimerData.ts b/apps/client/src/views/timer/useTimerData.ts index 9ec9c24a5..406912e0b 100644 --- a/apps/client/src/views/timer/useTimerData.ts +++ b/apps/client/src/views/timer/useTimerData.ts @@ -6,7 +6,7 @@ import useRundown from '../../common/hooks-query/useRundown'; import useSettings from '../../common/hooks-query/useSettings'; import useViewSettings from '../../common/hooks-query/useViewSettings'; import { useViewOptionsStore } from '../../common/stores/viewOptions'; -import { aggregateQueryStatus, ViewData } from '../utils/viewLoader.utils'; +import { ViewData, aggregateQueryStatus } from '../utils/viewLoader.utils'; export interface TimerData { customFields: CustomFields; diff --git a/apps/client/tsconfig.tests.json b/apps/client/tsconfig.app.json similarity index 65% rename from apps/client/tsconfig.tests.json rename to apps/client/tsconfig.app.json index 3c993fe9b..14ad637d9 100644 --- a/apps/client/tsconfig.tests.json +++ b/apps/client/tsconfig.app.json @@ -1,5 +1,5 @@ { - "extends": "../../tsconfig.tests.json", + "extends": "../../tsconfig.common.json", "compilerOptions": { "target": "esnext", "lib": [ @@ -9,32 +9,31 @@ ], "types": [ "vite/client", - "vite-plugin-svgr/client", - "vitest/globals" + "vite-plugin-svgr/client" ], "module": "esnext", - "moduleResolution": "node", + "moduleResolution": "bundler", "allowUnusedLabels": false, "removeComments": true, "preserveConstEnums": true, "allowJs": true, - "baseUrl": "src", "jsx": "react-jsx", - "outDir": "build", - "composite": true + "outDir": "build" }, "include": [ + "src" + ], + "typeRoots": [ + "./src/declarations/**" + ], + "exclude": [ + "node_modules", + "build", + "src/**/__tests__/**", + "src/**/__test__/**", "src/**/*.test.ts", "src/**/*.test.tsx", "src/**/*.spec.ts", "src/**/*.spec.tsx", - ], - "references": [ - { - "path": "./tsconfig.json" - } - ], - "typeRoots": [ - "./src/declarations/**" ] } diff --git a/apps/client/tsconfig.json b/apps/client/tsconfig.json index 4ea66fe3d..8a09adcb0 100644 --- a/apps/client/tsconfig.json +++ b/apps/client/tsconfig.json @@ -1,44 +1,8 @@ { - "extends": "../../tsconfig.common.json", - "compilerOptions": { - "target": "esnext", - "composite": true, - "lib": [ - "dom", - "dom.iterable", - "esnext" - ], - "types": [ - "vite/client", - "vite-plugin-svgr/client" - ], - "module": "esnext", - "moduleResolution": "node", - "allowUnusedLabels": false, - "removeComments": true, - "preserveConstEnums": true, - "allowJs": true, - "baseUrl": "src", - "jsx": "react-jsx", - "outDir": "build" - }, - "include": [ - "src" - ], - "typeRoots": [ - "./src/declarations/**" - ], - "exclude": [ - "node_modules", - "build", - "src/**/*.test.ts", - "src/**/*.test.tsx", - "src/**/*.spec.ts", - "src/**/*.spec.tsx", - ], + "extends": "./tsconfig.app.json", + "files": [], + "include": [], "references": [ - { - "path": "./tsconfig.tests.json" - } + { "path": "./tsconfig.vitest.json" } ] } diff --git a/apps/client/tsconfig.vitest.json b/apps/client/tsconfig.vitest.json new file mode 100644 index 000000000..fc4ffc252 --- /dev/null +++ b/apps/client/tsconfig.vitest.json @@ -0,0 +1,18 @@ +{ + "extends": "./tsconfig.app.json", + "compilerOptions": { + "composite": true, + "types": [ + "vite/client", + "vite-plugin-svgr/client", + "vitest/globals" + ] + }, + "include": [ + "src" + ], + "exclude": [ + "node_modules", + "build" + ] +} diff --git a/apps/client/vite.config.js b/apps/client/vite.config.js index b9e42ff7d..372f75f2f 100644 --- a/apps/client/vite.config.js +++ b/apps/client/vite.config.js @@ -1,6 +1,7 @@ +import path from 'path'; + import { sentryVitePlugin } from '@sentry/vite-plugin'; import react from '@vitejs/plugin-react'; -import path from 'path'; import { defineConfig } from 'vite'; import { compression } from 'vite-plugin-compression2'; import svgrPlugin from 'vite-plugin-svgr'; diff --git a/apps/electron/.eslintignore b/apps/electron/.eslintignore deleted file mode 100644 index aeec03c89..000000000 --- a/apps/electron/.eslintignore +++ /dev/null @@ -1,3 +0,0 @@ -node_modules -dist -assets \ No newline at end of file diff --git a/apps/electron/.eslintrc b/apps/electron/.eslintrc deleted file mode 100644 index 192099671..000000000 --- a/apps/electron/.eslintrc +++ /dev/null @@ -1,16 +0,0 @@ -{ - "parserOptions": { - "sourceType": "module" - }, - "env": { - "browser": true, - "node": true - }, - "extends": [ - "eslint:recommended" - ], - "plugins": [], - "rules": { - "@typescript-eslint/no-var-requires": "off" - } -} diff --git a/apps/electron/.oxlintrc.json b/apps/electron/.oxlintrc.json new file mode 100644 index 000000000..f43f3d72f --- /dev/null +++ b/apps/electron/.oxlintrc.json @@ -0,0 +1,5 @@ +{ + "$schema": "../../node_modules/oxlint/configuration_schema.json", + "extends": ["../../.oxlintrc.json"], + "plugins": ["unicorn", "typescript", "oxc", "vitest"] +} diff --git a/apps/electron/package.json b/apps/electron/package.json index 8504f4d9b..2fd147d79 100644 --- a/apps/electron/package.json +++ b/apps/electron/package.json @@ -15,14 +15,11 @@ "devDependencies": { "electron": "38.2.1", "electron-builder": "26.0.18", - "eslint": "catalog:", - "eslint-config-prettier": "catalog:", - "prettier": "catalog:", "wait-on": "^7.2.0" }, "scripts": { "dev:electron": "wait-on http://localhost:3000 && cross-env NODE_ENV=development electron .", - "lint": "eslint . --quiet", + "lint": "oxlint --quiet --type-aware", "dist-win": "electron-builder --publish=never --x64 --win", "dist-mac": "electron-builder --publish=never --mac", "dist-linux": "electron-builder --publish=never --linux" @@ -69,12 +66,12 @@ }, "linux": { "target": { - "target": "AppImage", - "arch": [ - "x64", - "arm64", - "armv7l" - ] + "target": "AppImage", + "arch": [ + "x64", + "arm64", + "armv7l" + ] }, "artifactName": "ontime-linux-${arch}.AppImage" }, diff --git a/apps/electron/src/splash/splash.html b/apps/electron/src/splash/splash.html index d9b75c0d1..081147904 100644 --- a/apps/electron/src/splash/splash.html +++ b/apps/electron/src/splash/splash.html @@ -1,4 +1,4 @@ - + diff --git a/apps/resolver/.eslintignore b/apps/resolver/.eslintignore deleted file mode 100644 index a0270fb28..000000000 --- a/apps/resolver/.eslintignore +++ /dev/null @@ -1,2 +0,0 @@ -node_modules -dist \ No newline at end of file diff --git a/apps/resolver/.oxlintrc.json b/apps/resolver/.oxlintrc.json new file mode 100644 index 000000000..f43f3d72f --- /dev/null +++ b/apps/resolver/.oxlintrc.json @@ -0,0 +1,5 @@ +{ + "$schema": "../../node_modules/oxlint/configuration_schema.json", + "extends": ["../../.oxlintrc.json"], + "plugins": ["unicorn", "typescript", "oxc", "vitest"] +} diff --git a/apps/resolver/README.md b/apps/resolver/README.md index b4758c38a..69b3f8f84 100644 --- a/apps/resolver/README.md +++ b/apps/resolver/README.md @@ -2,14 +2,16 @@ Congratulations! You got this far into Ontime's rabbit hole and want to manage your installation. -The Resolver is an attempt to expose our ontime's api so it is easier to integrate with +The Resolver is an attempt to expose our ontime's api so it is easier to integrate with ## Links + - [Ontime's repository](https://github.com/cpvalente/ontime) - [Ontime's documentation](https://docs.getontime.no/) - [Ontime's website](https://getontime.no/) ## Sponsoring + You can help the development of this project or say thank you with a one time donation. \ See the [terms of donations](https://github.com/cpvalente/ontime/blob/master/SPONSOR.md) diff --git a/apps/resolver/package.json b/apps/resolver/package.json index 1f168e296..851a787a4 100644 --- a/apps/resolver/package.json +++ b/apps/resolver/package.json @@ -7,23 +7,27 @@ "main": "./dist/main.js", "description": "shared typings for ontime", "scripts": { - "lint": "eslint . --quiet", + "lint": "oxlint --quiet --type-aware", "typecheck": "tsc --noEmit", "prebuild": "pnpm rimraf ./dist", "build": "tsup && pnpm rimraf ./dist/index.js", "postbuild": "pnpm rimraf ./dist/index.d.ts" }, - "keywords": ["ontime", "resolver", "parser"], + "keywords": [ + "ontime", + "resolver", + "parser" + ], "author": "", "license": "AGPL-3.0-only", "devDependencies": { "@sprout2000/esbuild-copy-plugin": "^1.1.19", - "@typescript-eslint/parser": "catalog:", - "eslint": "catalog:", - "tsup": "^8.5.0", + "ontime-types": "workspace:^4.2.1", "rimraf": "catalog:", - "typescript": "catalog:", - "ontime-types": "workspace:^4.2.1" + "tsup": "^8.5.0", + "typescript": "catalog:" }, - "files": ["dist"] + "files": [ + "dist" + ] } diff --git a/apps/resolver/tsconfig.dts.json b/apps/resolver/tsconfig.dts.json new file mode 100644 index 000000000..35bcdb26a --- /dev/null +++ b/apps/resolver/tsconfig.dts.json @@ -0,0 +1,6 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "ignoreDeprecations": "6.0" + } +} diff --git a/apps/resolver/tsconfig.json b/apps/resolver/tsconfig.json index 7a6b17b62..4346749d7 100644 --- a/apps/resolver/tsconfig.json +++ b/apps/resolver/tsconfig.json @@ -11,7 +11,7 @@ "declaration": true, "outDir": "dist", "sourceMap": true, - "baseUrl": "src", + "ignoreDeprecations": "6.0" }, "include": [ "src", @@ -20,10 +20,5 @@ "node_modules", "src/**/*.test.ts", "src/**/*.spec.ts", - ], - "references": [ - { - "path": "./tsconfig.tests.json" - } ] } diff --git a/apps/resolver/tsup.config.js b/apps/resolver/tsup.config.js index e5f6a5f9c..61396a66c 100644 --- a/apps/resolver/tsup.config.js +++ b/apps/resolver/tsup.config.js @@ -1,13 +1,13 @@ -import { defineConfig } from 'tsup'; import copyPlugin from '@sprout2000/esbuild-copy-plugin'; +import { defineConfig } from 'tsup'; -export default defineConfig({ +const config = defineConfig({ clean: false, // we can't use clean as it runs after the copy plugin entry: ['src/main.ts'], outDir: 'dist', bundle: true, - dts: { resolve: true }, + dts: { resolve: true, tsconfig: './tsconfig.dts.json' }, format: 'esm', target: 'esnext', platform: 'node', @@ -18,3 +18,5 @@ export default defineConfig({ }), ], }); + +export default config; diff --git a/apps/server/.eslintignore b/apps/server/.eslintignore deleted file mode 100644 index a0270fb28..000000000 --- a/apps/server/.eslintignore +++ /dev/null @@ -1,2 +0,0 @@ -node_modules -dist \ No newline at end of file diff --git a/apps/server/.eslintrc b/apps/server/.eslintrc deleted file mode 100644 index ec1e6589c..000000000 --- a/apps/server/.eslintrc +++ /dev/null @@ -1,12 +0,0 @@ -{ - "env": { - "node": true - }, - "parserOptions": { - "ecmaVersion": 2020, - "sourceType": "module" - }, - "globals": { - "globalThis": false - } -} diff --git a/apps/server/.oxlintrc.json b/apps/server/.oxlintrc.json new file mode 100644 index 000000000..39c7b723b --- /dev/null +++ b/apps/server/.oxlintrc.json @@ -0,0 +1,5 @@ +{ + "$schema": "../../node_modules/oxlint/configuration_schema.json", + "extends": ["../../.oxlintrc.json"], + "plugins": ["unicorn", "typescript", "oxc", "vitest", "node", "promise"] +} diff --git a/apps/server/.prettierrc b/apps/server/.prettierrc deleted file mode 100644 index 191bc273f..000000000 --- a/apps/server/.prettierrc +++ /dev/null @@ -1,8 +0,0 @@ -{ - "endOfLine": "lf", - "trailingComma": "all", - "tabWidth": 2, - "semi": true, - "singleQuote": true, - "printWidth": 120 -} diff --git a/apps/server/esbuild.js b/apps/server/esbuild.js index 584263362..6e6bc4c67 100644 --- a/apps/server/esbuild.js +++ b/apps/server/esbuild.js @@ -1,16 +1,17 @@ -import * as esbuild from 'esbuild'; - -const isDocker = process.env.NODE_ENV === 'docker'; - -await esbuild.build({ - logLevel: 'error', - platform: 'node', - target: ['node20'], - format: 'cjs', - bundle: true, - minify: true, - legalComments: 'external', - dropLabels: ['DEV'], - entryPoints: isDocker ? ['src/index.ts'] : ['src/app.ts'], - outfile: isDocker ? 'dist/docker.cjs' : 'dist/index.cjs', -}); +import * as esbuild from 'esbuild'; + +const isDocker = process.env.NODE_ENV === 'docker'; + +await esbuild.build({ + logLevel: 'error', + platform: 'node', + target: ['node20'], + format: 'cjs', + tsconfig: 'tsconfig.app.json', + bundle: true, + minify: true, + legalComments: 'external', + dropLabels: ['DEV'], + entryPoints: isDocker ? ['src/index.ts'] : ['src/app.ts'], + outfile: isDocker ? 'dist/docker.cjs' : 'dist/index.cjs', +}); diff --git a/apps/server/package.json b/apps/server/package.json index 0af5671fb..6cd814d56 100644 --- a/apps/server/package.json +++ b/apps/server/package.json @@ -13,10 +13,10 @@ "express": "5.1.0", "express-static-gzip": "3.0.0", "express-validator": "7.2.1", - "multer": "2.1.0", "fast-equals": "^5.0.1", "google-auth-library": "^9.4.2", "lowdb": "^7.0.1", + "multer": "2.1.0", "ontime-utils": "workspace:*", "osc-min": "2.1.2", "sanitize-filename": "^1.6.3", @@ -31,13 +31,8 @@ "@types/node": "catalog:", "@types/websocket": "^1.0.5", "@types/ws": "^8.5.10", - "@typescript-eslint/eslint-plugin": "catalog:", - "@typescript-eslint/parser": "catalog:", "esbuild": "^0.24.0", - "eslint": "catalog:", - "eslint-plugin-prettier": "catalog:", "ontime-types": "workspace:*", - "prettier": "catalog:", "server-timing": "^3.3.3", "shx": "^0.3.4", "ts-essentials": "catalog:", @@ -48,17 +43,13 @@ "scripts": { "addversion": "node -p \"'export const ONTIME_VERSION = ' + JSON.stringify(require('../../package.json').version) + ';'\" > src/ONTIME_VERSION.js", "postinstall": "pnpm addversion", - - "dev": "cross-env NODE_ENV=development tsx watch ./src/index.ts", + "dev": "cross-env NODE_ENV=development tsx watch --tsconfig tsconfig.app.json ./src/index.ts", "dev:electron": "pnpm dev", - "dev:inspect": "cross-env NODE_ENV=development tsx watch --inspect ./src/index.ts", - - "lint": "eslint . --quiet", - "typecheck": "tsc --noEmit", - - "prebuild": "tsx ./scripts/bundleCss.ts && tsx ./scripts/bundleTranslation.ts", + "dev:inspect": "cross-env NODE_ENV=development tsx watch --tsconfig tsconfig.app.json --inspect ./src/index.ts", + "lint": "oxlint --quiet --type-aware", + "typecheck": "tsc -p tsconfig.app.json --noEmit", + "prebuild": "tsx --tsconfig tsconfig.app.json ./scripts/bundleCss.ts && tsx --tsconfig tsconfig.app.json ./scripts/bundleTranslation.ts", "build": "node esbuild.js", - "test": "cross-env IS_TEST=true vitest", "test:inspect": "cross-env IS_TEST=true vitest --inspect --no-file-parallelism", "test:pipeline": "cross-env IS_TEST=true vitest run" diff --git a/apps/server/src/adapters/OscAdapter.ts b/apps/server/src/adapters/OscAdapter.ts index 77776f172..06ce82863 100644 --- a/apps/server/src/adapters/OscAdapter.ts +++ b/apps/server/src/adapters/OscAdapter.ts @@ -1,14 +1,13 @@ -import { LogOrigin } from 'ontime-types'; - -import { fromBuffer, type OscPacketOutput } from 'osc-min'; import * as dgram from 'node:dgram'; -import { logger } from '../classes/Logger.js'; -import { dispatchFromAdapter } from '../api-integration/integration.controller.js'; -import { isOntimeCloud } from '../setup/environment.js'; +import { LogOrigin } from 'ontime-types'; +import { type OscPacketOutput, fromBuffer } from 'osc-min'; -import { integrationPayloadFromPath } from './utils/parse.js'; +import { dispatchFromAdapter } from '../api-integration/integration.controller.js'; +import { logger } from '../classes/Logger.js'; +import { isOntimeCloud } from '../setup/environment.js'; import type { IAdapter } from './IAdapter.js'; +import { integrationPayloadFromPath } from './utils/parse.js'; class OscServer implements IAdapter { private udpSocket: dgram.Socket | null = null; diff --git a/apps/server/src/adapters/WebsocketAdapter.ts b/apps/server/src/adapters/WebsocketAdapter.ts index 036e7cd44..531429c17 100644 --- a/apps/server/src/adapters/WebsocketAdapter.ts +++ b/apps/server/src/adapters/WebsocketAdapter.ts @@ -14,26 +14,26 @@ * Payload: adds necessary payload for the request to be completed */ +import type { Server } from 'http'; + import { Client, LogOrigin, - WsPacketToClient, - WsPacketToServer, + MaybeNumber, MessageTag, RefetchKey, - MaybeNumber, + WsPacketToClient, + WsPacketToServer, } from 'ontime-types'; - +import { generateId } from 'ontime-utils'; import { WebSocket, WebSocketServer } from 'ws'; -import type { Server } from 'http'; +import { dispatchFromAdapter } from '../api-integration/integration.controller.js'; +import { logger } from '../classes/Logger.js'; +import { authenticateSocket } from '../middleware/authenticate.js'; +import { eventStore } from '../stores/EventStore.js'; import getRandomName from '../utils/getRandomName.js'; import type { IAdapter } from './IAdapter.js'; -import { eventStore } from '../stores/EventStore.js'; -import { logger } from '../classes/Logger.js'; -import { dispatchFromAdapter } from '../api-integration/integration.controller.js'; -import { generateId } from 'ontime-utils'; -import { authenticateSocket } from '../middleware/authenticate.js'; type ClientId = string; let instance: SocketServer | null = null; diff --git a/apps/server/src/api-data/assets/assets.router.ts b/apps/server/src/api-data/assets/assets.router.ts index d74e5fca3..2a3ca199d 100644 --- a/apps/server/src/api-data/assets/assets.router.ts +++ b/apps/server/src/api-data/assets/assets.router.ts @@ -1,11 +1,12 @@ import express from 'express'; import type { Request, Response } from 'express'; -import { RefetchKey, type ErrorResponse } from 'ontime-types'; -import { validatePostCss, validatePostTranslation } from './assets.validation.js'; -import { readCssFile, writeCssFile, writeUserTranslation } from './assets.service.js'; +import { type ErrorResponse, RefetchKey } from 'ontime-types'; import { getErrorMessage } from 'ontime-utils'; -import { defaultCss } from '../../user/styles/bundledCss.js'; + import { sendRefetch } from '../../adapters/WebsocketAdapter.js'; +import { defaultCss } from '../../user/styles/bundledCss.js'; +import { readCssFile, writeCssFile, writeUserTranslation } from './assets.service.js'; +import { validatePostCss, validatePostTranslation } from './assets.validation.js'; export const router = express.Router(); diff --git a/apps/server/src/api-data/assets/assets.service.ts b/apps/server/src/api-data/assets/assets.service.ts index 4e208a2ca..17f31e649 100644 --- a/apps/server/src/api-data/assets/assets.service.ts +++ b/apps/server/src/api-data/assets/assets.service.ts @@ -1,8 +1,8 @@ -import type { TranslationObject } from 'ontime-types'; - import { existsSync } from 'node:fs'; import { readFile, writeFile } from 'node:fs/promises'; +import type { TranslationObject } from 'ontime-types'; + import { publicFiles } from '../../setup/index.js'; import { defaultCss } from '../../user/styles/bundledCss.js'; diff --git a/apps/server/src/api-data/automation/__tests__/automation.dao.test.ts b/apps/server/src/api-data/automation/__tests__/automation.dao.test.ts index bacdf5db2..ed5464a5d 100644 --- a/apps/server/src/api-data/automation/__tests__/automation.dao.test.ts +++ b/apps/server/src/api-data/automation/__tests__/automation.dao.test.ts @@ -1,41 +1,37 @@ -import { TriggerDTO, TimerLifeCycle, AutomationDTO, Automation, ProjectRundowns } from 'ontime-types'; +import { Automation, AutomationDTO, ProjectRundowns, TimerLifeCycle, TriggerDTO } from 'ontime-types'; import { makeOntimeEvent } from '../../rundown/__mocks__/rundown.mocks.js'; - import { - addTrigger, addAutomation, + addTrigger, deleteAll, deleteAllTriggers, - deleteTrigger, deleteAutomation, - editTrigger, + deleteTrigger, editAutomation, + editTrigger, getAutomationTriggers, getAutomations, } from '../automation.dao.js'; +import { makeHTTPAction, makeOSCAction } from './testUtils.js'; -import { makeOSCAction, makeHTTPAction } from './testUtils.js'; - -beforeAll(() => { - vi.mock('../../../classes/data-provider/DataProvider.js', () => { - // Create a small mock store - let automations = { - enabledAutomations: true, - enabledOscIn: true, - oscPortIn: 8888, - triggers: [], - automations: {}, - }; - return { - getDataProvider: vi.fn().mockImplementation(() => { - return { - getAutomation: vi.fn().mockImplementation(() => automations), - setAutomation: vi.fn().mockImplementation((newData) => (automations = newData)), - }; - }), - }; - }); +vi.mock('../../../classes/data-provider/DataProvider.js', () => { + // Create a small mock store + let automations = { + enabledAutomations: true, + enabledOscIn: true, + oscPortIn: 8888, + triggers: [], + automations: {}, + }; + return { + getDataProvider: vi.fn().mockImplementation(() => { + return { + getAutomation: vi.fn().mockImplementation(() => automations), + setAutomation: vi.fn().mockImplementation((newData) => (automations = newData)), + }; + }), + }; }); afterAll(() => { @@ -141,7 +137,7 @@ describe('addAutomation()', () => { }); }); -describe('editAutomation()', async () => { +describe('editAutomation()', () => { // saving the ID of the added automation let firstAutomation: Automation; beforeEach(async () => { diff --git a/apps/server/src/api-data/automation/__tests__/automation.service.test.ts b/apps/server/src/api-data/automation/__tests__/automation.service.test.ts index 5d8b66c64..8ed92a9b9 100644 --- a/apps/server/src/api-data/automation/__tests__/automation.service.test.ts +++ b/apps/server/src/api-data/automation/__tests__/automation.service.test.ts @@ -1,35 +1,31 @@ import { PlayableEvent, TimerLifeCycle } from 'ontime-types'; import { makeRuntimeStoreData } from '../../../stores/__mocks__/runtimeStore.mocks.js'; - -import { deleteAllTriggers, addTrigger, addAutomation } from '../automation.dao.js'; -import { testConditions, triggerAutomations } from '../automation.service.js'; -import * as oscClient from '../clients/osc.client.js'; -import * as httpClient from '../clients/http.client.js'; - -import { makeOSCAction, makeHTTPAction } from './testUtils.js'; import { RuntimeState } from '../../../stores/runtimeState.js'; import { makeOntimeEvent } from '../../rundown/__mocks__/rundown.mocks.js'; +import { addAutomation, addTrigger, deleteAllTriggers } from '../automation.dao.js'; +import { testConditions, triggerAutomations } from '../automation.service.js'; +import * as httpClient from '../clients/http.client.js'; +import * as oscClient from '../clients/osc.client.js'; +import { makeHTTPAction, makeOSCAction } from './testUtils.js'; -beforeAll(() => { - vi.mock('../../../classes/data-provider/DataProvider.js', () => { - // Create a small mock store - let automations = { - enabledAutomations: true, - enabledOscIn: true, - oscPortIn: 8888, - triggers: [], - automations: {}, - }; - return { - getDataProvider: vi.fn().mockImplementation(() => { - return { - getAutomation: vi.fn().mockImplementation(() => automations), - setAutomation: vi.fn().mockImplementation((newData) => (automations = newData)), - }; - }), - }; - }); +vi.mock('../../../classes/data-provider/DataProvider.js', () => { + // Create a small mock store + let automations = { + enabledAutomations: true, + enabledOscIn: true, + oscPortIn: 8888, + triggers: [], + automations: {}, + }; + return { + getDataProvider: vi.fn().mockImplementation(() => { + return { + getAutomation: vi.fn().mockImplementation(() => automations), + setAutomation: vi.fn().mockImplementation((newData) => (automations = newData)), + }; + }), + }; }); afterAll(() => { @@ -41,7 +37,7 @@ describe('triggerAction()', () => { let httpSpy = vi.spyOn(httpClient, 'emitHTTP'); beforeAll(() => { - vi.mock('../../../stores/EventStore.js', () => { + vi.doMock('../../../stores/EventStore.js', () => { // Create a small mock store return { eventStore: { @@ -49,11 +45,11 @@ describe('triggerAction()', () => { }, }; }); - }) + }); beforeEach(async () => { - oscSpy = vi.spyOn(oscClient, 'emitOSC').mockImplementation(() => { }); - httpSpy = vi.spyOn(httpClient, 'emitHTTP').mockImplementation(() => { }); + oscSpy = vi.spyOn(oscClient, 'emitOSC').mockImplementation(() => {}); + httpSpy = vi.spyOn(httpClient, 'emitHTTP').mockImplementation(() => {}); await deleteAllTriggers(); const oscAutomation = await addAutomation({ diff --git a/apps/server/src/api-data/automation/__tests__/automation.utils.test.ts b/apps/server/src/api-data/automation/__tests__/automation.utils.test.ts index e6e9f6c14..06cb09487 100644 --- a/apps/server/src/api-data/automation/__tests__/automation.utils.test.ts +++ b/apps/server/src/api-data/automation/__tests__/automation.utils.test.ts @@ -1,7 +1,6 @@ import { ProjectRundowns, TimerLifeCycle } from 'ontime-types'; import { makeOntimeEvent } from '../../rundown/__mocks__/rundown.mocks.js'; - import { isAutomationUsed, parseTemplateNested, stringToOSCArgs } from '../automation.utils.js'; describe('parseTemplateNested()', () => { diff --git a/apps/server/src/api-data/automation/__tests__/automation.validation.test.ts b/apps/server/src/api-data/automation/__tests__/automation.validation.test.ts index 2c7252485..0ec82b633 100644 --- a/apps/server/src/api-data/automation/__tests__/automation.validation.test.ts +++ b/apps/server/src/api-data/automation/__tests__/automation.validation.test.ts @@ -22,7 +22,7 @@ describe('parseOutput', () => { address: '/test', args: 'test', }; - expect(() => parseOutput(payload)).toThrow(); + expect(() => parseOutput(payload)).toThrow('Unexpected payload type:'); }); }); describe('handles HTTP outputs', () => { @@ -39,7 +39,7 @@ describe('parseOutput', () => { const payload = { type: 'http', }; - expect(() => parseOutput(payload)).toThrow(); + expect(() => parseOutput(payload)).toThrow('Unexpected payload type:'); }); }); describe('handles Ontime outputs', () => { @@ -79,7 +79,7 @@ describe('parseOutput', () => { type: 'ontime', action: 'not-exist', }; - expect(() => parseOutput(payload)).toThrow(); + expect(() => parseOutput(payload)).toThrow('Invalid Ontime action'); }); it('parses message-set', () => { @@ -122,45 +122,46 @@ describe('parseOutput', () => { text: 123, visible: '', }), - ).toThrow(); + ).toThrow('Unexpected payload type:'); }); - it('parses message-secondary', () => {}); - expect( - parseOutput({ - type: 'ontime', - action: 'message-secondary', - secondarySource: 'test', - }), - ).toMatchObject({ - secondarySource: null, - }); - expect( - parseOutput({ - type: 'ontime', - action: 'message-secondary', - secondarySource: '', - }), - ).toMatchObject({ - secondarySource: null, - }); - expect( - parseOutput({ - type: 'ontime', - action: 'message-secondary', + it('parses message-secondary', () => { + expect( + parseOutput({ + type: 'ontime', + action: 'message-secondary', + secondarySource: 'test', + }), + ).toMatchObject({ + secondarySource: null, + }); + expect( + parseOutput({ + type: 'ontime', + action: 'message-secondary', + secondarySource: '', + }), + ).toMatchObject({ + secondarySource: null, + }); + expect( + parseOutput({ + type: 'ontime', + action: 'message-secondary', + secondarySource: 'aux1', + }), + ).toMatchObject({ secondarySource: 'aux1', - }), - ).toMatchObject({ - secondarySource: 'aux1', - }); - expect( - parseOutput({ - type: 'ontime', - action: 'message-secondary', + }); + expect( + parseOutput({ + type: 'ontime', + action: 'message-secondary', + secondarySource: 'secondary', + }), + ).toMatchObject({ secondarySource: 'secondary', - }), - ).toMatchObject({ - secondarySource: 'secondary', + }); }); }); }); diff --git a/apps/server/src/api-data/automation/__tests__/testUtils.ts b/apps/server/src/api-data/automation/__tests__/testUtils.ts index b3951b288..0767d0689 100644 --- a/apps/server/src/api-data/automation/__tests__/testUtils.ts +++ b/apps/server/src/api-data/automation/__tests__/testUtils.ts @@ -1,4 +1,4 @@ -import { OSCOutput, HTTPOutput } from 'ontime-types'; +import { HTTPOutput, OSCOutput } from 'ontime-types'; export function makeOSCAction(action?: Partial): OSCOutput { return { diff --git a/apps/server/src/api-data/automation/automation.controller.ts b/apps/server/src/api-data/automation/automation.controller.ts index 9e4a84691..590232b1b 100644 --- a/apps/server/src/api-data/automation/automation.controller.ts +++ b/apps/server/src/api-data/automation/automation.controller.ts @@ -1,11 +1,9 @@ -import { getErrorMessage } from 'ontime-utils'; -import { Automation, AutomationSettings, ErrorResponse, Trigger } from 'ontime-types'; - import type { Request, Response } from 'express'; +import { Automation, AutomationSettings, ErrorResponse, Trigger } from 'ontime-types'; +import { getErrorMessage } from 'ontime-utils'; import { oscServer } from '../../adapters/OscAdapter.js'; import { getDataProvider } from '../../classes/data-provider/DataProvider.js'; - import * as automationDao from './automation.dao.js'; import * as automationService from './automation.service.js'; import { parseOutput } from './automation.validation.js'; diff --git a/apps/server/src/api-data/automation/automation.dao.ts b/apps/server/src/api-data/automation/automation.dao.ts index 409571b1a..464df87e4 100644 --- a/apps/server/src/api-data/automation/automation.dao.ts +++ b/apps/server/src/api-data/automation/automation.dao.ts @@ -10,7 +10,6 @@ import type { import { deleteAtIndex, generateId } from 'ontime-utils'; import { getDataProvider } from '../../classes/data-provider/DataProvider.js'; - import { isAutomationUsed } from './automation.utils.js'; /** diff --git a/apps/server/src/api-data/automation/automation.parser.ts b/apps/server/src/api-data/automation/automation.parser.ts index e01c126e6..085535790 100644 --- a/apps/server/src/api-data/automation/automation.parser.ts +++ b/apps/server/src/api-data/automation/automation.parser.ts @@ -1,7 +1,7 @@ -import { DatabaseModel, AutomationSettings, NormalisedAutomation, Trigger } from 'ontime-types'; +import { AutomationSettings, DatabaseModel, NormalisedAutomation, Trigger } from 'ontime-types'; -import type { ErrorEmitter } from '../../utils/parserUtils.js'; import { getPartialProject } from '../../models/dataModel.js'; +import type { ErrorEmitter } from '../../utils/parserUtils.js'; export function parseAutomationSettings(data: Partial, emitError?: ErrorEmitter): AutomationSettings { const defaultAutomation: AutomationSettings = getPartialProject('automation'); diff --git a/apps/server/src/api-data/automation/automation.router.ts b/apps/server/src/api-data/automation/automation.router.ts index abd87d964..a46ac684e 100644 --- a/apps/server/src/api-data/automation/automation.router.ts +++ b/apps/server/src/api-data/automation/automation.router.ts @@ -1,25 +1,25 @@ import express from 'express'; +import { paramsWithId } from '../validation-utils/validationFunction.js'; import { - deleteTrigger, deleteAutomation, + deleteTrigger, editAutomation, getAutomationSettings, - postTrigger, postAutomation, - putTrigger, postAutomationSettings, + postTrigger, + putTrigger, testOutput, } from './automation.controller.js'; import { - validateAutomationSettings, validateAutomation, validateAutomationPatch, + validateAutomationSettings, validateTestPayload, validateTrigger, validateTriggerPatch, } from './automation.validation.js'; -import { paramsWithId } from '../validation-utils/validationFunction.js'; export const router = express.Router(); diff --git a/apps/server/src/api-data/automation/automation.service.ts b/apps/server/src/api-data/automation/automation.service.ts index 6e7b9ebba..91b0aee26 100644 --- a/apps/server/src/api-data/automation/automation.service.ts +++ b/apps/server/src/api-data/automation/automation.service.ts @@ -1,25 +1,24 @@ import { - isHTTPOutput, - isOntimeAction, - isOSCOutput, - LogOrigin, - RuntimeStore, - TimerLifeCycle, type AutomationFilter, type AutomationOutput, type FilterRule, + LogOrigin, + RuntimeStore, + TimerLifeCycle, + isHTTPOutput, + isOSCOutput, + isOntimeAction, } from 'ontime-types'; import { getPropertyFromPath } from 'ontime-utils'; -import { emitOSC } from './clients/osc.client.js'; -import { emitHTTP } from './clients/http.client.js'; -import { getAutomationsEnabled, getAutomations, getAutomationTriggers } from './automation.dao.js'; -import { isContained, isEquivalent, isGreaterThan, isLessThan } from './automation.utils.js'; -import { toOntimeAction } from './clients/ontime.client.js'; - import { logger } from '../../classes/Logger.js'; import { isOntimeCloud } from '../../setup/environment.js'; import { eventStore } from '../../stores/EventStore.js'; +import { getAutomationTriggers, getAutomations, getAutomationsEnabled } from './automation.dao.js'; +import { isContained, isEquivalent, isGreaterThan, isLessThan } from './automation.utils.js'; +import { emitHTTP } from './clients/http.client.js'; +import { toOntimeAction } from './clients/ontime.client.js'; +import { emitOSC } from './clients/osc.client.js'; /** * Exposes a method for triggering actions based on a TimerLifeCycle event diff --git a/apps/server/src/api-data/automation/automation.utils.ts b/apps/server/src/api-data/automation/automation.utils.ts index 2eea318a8..53546a044 100644 --- a/apps/server/src/api-data/automation/automation.utils.ts +++ b/apps/server/src/api-data/automation/automation.utils.ts @@ -1,15 +1,15 @@ import { EntryId, FilterRule, - isOntimeEvent, MaybeNumber, OntimeAction, - ontimeActionKeyValues, ProjectRundowns, RundownEntries, + isOntimeEvent, + ontimeActionKeyValues, } from 'ontime-types'; -import { millisToString, removeLeadingZero, splitWhitespace, getPropertyFromPath } from 'ontime-utils'; -import type { OscArgOrArrayInput, OscArgInput } from 'osc-min'; +import { getPropertyFromPath, millisToString, removeLeadingZero, splitWhitespace } from 'ontime-utils'; +import type { OscArgInput, OscArgOrArrayInput } from 'osc-min'; type FilterOperator = 'equals' | 'not_equals' | 'greater_than' | 'less_than' | 'contains'; diff --git a/apps/server/src/api-data/automation/automation.validation.ts b/apps/server/src/api-data/automation/automation.validation.ts index 5d92fdf03..98d2af828 100644 --- a/apps/server/src/api-data/automation/automation.validation.ts +++ b/apps/server/src/api-data/automation/automation.validation.ts @@ -1,20 +1,18 @@ +import { body, oneOf, param } from 'express-validator'; import { Automation, AutomationFilter, AutomationOutput, HTTPOutput, - OntimeAction, OSCOutput, + OntimeAction, SecondarySource, timerLifecycleValues, } from 'ontime-types'; -import { body, oneOf, param } from 'express-validator'; - import * as assert from '../../utils/assert.js'; - -import { isFilterOperator, isFilterRule, isOntimeActionAction } from './automation.utils.js'; import { requestValidationFunction } from '../validation-utils/validationFunction.js'; +import { isFilterOperator, isFilterRule, isOntimeActionAction } from './automation.utils.js'; export const validateAutomationSettings = [ body('enabledAutomations').isBoolean(), diff --git a/apps/server/src/api-data/automation/clients/http.client.ts b/apps/server/src/api-data/automation/clients/http.client.ts index c66c80c77..676f0fc39 100644 --- a/apps/server/src/api-data/automation/clients/http.client.ts +++ b/apps/server/src/api-data/automation/clients/http.client.ts @@ -1,8 +1,7 @@ -import { DeepReadonly } from 'ts-essentials'; import { HTTPOutput, LogOrigin, RuntimeStore } from 'ontime-types'; +import { DeepReadonly } from 'ts-essentials'; import { logger } from '../../../classes/Logger.js'; - import { parseTemplateNested } from '../automation.utils.js'; /** diff --git a/apps/server/src/api-data/automation/clients/ontime.client.ts b/apps/server/src/api-data/automation/clients/ontime.client.ts index 366829bd7..51a9a8e3d 100644 --- a/apps/server/src/api-data/automation/clients/ontime.client.ts +++ b/apps/server/src/api-data/automation/clients/ontime.client.ts @@ -1,9 +1,9 @@ import { LogOrigin, OntimeAction } from 'ontime-types'; +import { parseUserTime } from 'ontime-utils'; import { logger } from '../../../classes/Logger.js'; import { auxTimerService } from '../../../services/aux-timer-service/AuxTimerService.js'; import * as messageService from '../../../services/message-service/message.service.js'; -import { parseUserTime } from 'ontime-utils'; export function toOntimeAction(action: OntimeAction) { const actionType = action.action; diff --git a/apps/server/src/api-data/automation/clients/osc.client.ts b/apps/server/src/api-data/automation/clients/osc.client.ts index c33f38003..b2b0f9c72 100644 --- a/apps/server/src/api-data/automation/clients/osc.client.ts +++ b/apps/server/src/api-data/automation/clients/osc.client.ts @@ -1,11 +1,11 @@ -import { LogOrigin, OSCOutput, RuntimeStore } from 'ontime-types'; - -import { type OscPacketInput, toBuffer as oscPacketToBuffer } from 'osc-min'; import * as dgram from 'node:dgram'; +import { LogOrigin, OSCOutput, RuntimeStore } from 'ontime-types'; +import { type OscPacketInput, toBuffer as oscPacketToBuffer } from 'osc-min'; +import { DeepReadonly } from 'ts-essentials'; + import { logger } from '../../../classes/Logger.js'; import { parseTemplateNested, stringToOSCArgs } from '../automation.utils.js'; -import { DeepReadonly } from 'ts-essentials'; const udpClient = dgram.createSocket('udp4'); diff --git a/apps/server/src/api-data/custom-fields/customFields.parser.ts b/apps/server/src/api-data/custom-fields/customFields.parser.ts index 3051ae395..8b0d71002 100644 --- a/apps/server/src/api-data/custom-fields/customFields.parser.ts +++ b/apps/server/src/api-data/custom-fields/customFields.parser.ts @@ -1,4 +1,4 @@ -import { DatabaseModel, CustomFields, CustomField } from 'ontime-types'; +import { CustomField, CustomFields, DatabaseModel } from 'ontime-types'; import { checkRegex, customFieldLabelToKey } from 'ontime-utils'; import type { ErrorEmitter } from '../../utils/parserUtils.js'; diff --git a/apps/server/src/api-data/custom-fields/customFields.router.ts b/apps/server/src/api-data/custom-fields/customFields.router.ts index 16757d684..e955ae2d7 100644 --- a/apps/server/src/api-data/custom-fields/customFields.router.ts +++ b/apps/server/src/api-data/custom-fields/customFields.router.ts @@ -1,14 +1,11 @@ +import express from 'express'; +import type { Request, Response } from 'express'; import { CustomField, CustomFields, ErrorResponse } from 'ontime-types'; import { getErrorMessage } from 'ontime-utils'; -import express from 'express'; -import type { Request, Response } from 'express'; - import { getDataProvider } from '../../classes/data-provider/DataProvider.js'; - import { getProjectCustomFields } from '../rundown/rundown.dao.js'; -import { createCustomField, editCustomField, deleteCustomField } from '../rundown/rundown.service.js'; - +import { createCustomField, deleteCustomField, editCustomField } from '../rundown/rundown.service.js'; import { validateCustomField, validateDeleteCustomField, validateEditCustomField } from './customFields.validation.js'; export const router = express.Router(); diff --git a/apps/server/src/api-data/custom-fields/customFields.validation.ts b/apps/server/src/api-data/custom-fields/customFields.validation.ts index 47b6021eb..9d374208b 100644 --- a/apps/server/src/api-data/custom-fields/customFields.validation.ts +++ b/apps/server/src/api-data/custom-fields/customFields.validation.ts @@ -1,6 +1,6 @@ +import { body, param } from 'express-validator'; import { checkRegex } from 'ontime-utils'; -import { body, param } from 'express-validator'; import { requestValidationFunction } from '../validation-utils/validationFunction.js'; export const validateCustomField = [ diff --git a/apps/server/src/api-data/db/__tests__/db.parser.test.ts b/apps/server/src/api-data/db/__tests__/db.parser.test.ts index df1efdf08..4f68895ed 100644 --- a/apps/server/src/api-data/db/__tests__/db.parser.test.ts +++ b/apps/server/src/api-data/db/__tests__/db.parser.test.ts @@ -3,21 +3,18 @@ import { SupportedEntry } from 'ontime-types'; import { demoDb } from '../../../models/demoProject.js'; - import { parseDatabaseModel } from '../db.parser.js'; // mock data provider -beforeAll(() => { - vi.mock('../../classes/data-provider/DataProvider.js', () => { - return { - getDataProvider: vi.fn().mockImplementation(() => { - return { - setRundown: vi.fn().mockImplementation((newData) => newData), - setCustomFields: vi.fn().mockImplementation((newData) => newData), - }; - }), - }; - }); +vi.mock('../../classes/data-provider/DataProvider.js', () => { + return { + getDataProvider: vi.fn().mockImplementation(() => { + return { + setRundown: vi.fn().mockImplementation((newData) => newData), + setCustomFields: vi.fn().mockImplementation((newData) => newData), + }; + }), + }; }); describe('test parseDatabaseModel() with demo project (valid)', () => { diff --git a/apps/server/src/api-data/db/db.controller.ts b/apps/server/src/api-data/db/db.controller.ts index 90d14a2ab..c45f2df63 100644 --- a/apps/server/src/api-data/db/db.controller.ts +++ b/apps/server/src/api-data/db/db.controller.ts @@ -1,3 +1,4 @@ +import type { Request, Response } from 'express'; import { DatabaseModel, ErrorResponse, @@ -7,17 +8,15 @@ import { TimeFormat, } from 'ontime-types'; import { getErrorMessage } from 'ontime-utils'; - -import type { Request, Response } from 'express'; import sanitize from 'sanitize-filename'; +import { getPartialProject } from '../../models/dataModel.js'; +import * as projectService from '../../services/project-service/ProjectService.js'; import { doesProjectExist, handleImageUpload, handleProjectUploaded, } from '../../services/project-service/projectServiceUtils.js'; -import * as projectService from '../../services/project-service/ProjectService.js'; -import { getPartialProject } from '../../models/dataModel.js'; export async function patchPartialProjectFile(req: Request, res: Response) { try { diff --git a/apps/server/src/api-data/db/db.parser.ts b/apps/server/src/api-data/db/db.parser.ts index 1db999604..606de4057 100644 --- a/apps/server/src/api-data/db/db.parser.ts +++ b/apps/server/src/api-data/db/db.parser.ts @@ -1,18 +1,17 @@ import { DatabaseModel, LogOrigin } from 'ontime-types'; +import { getErrorMessage } from 'ontime-utils'; import { logger } from '../../classes/Logger.js'; - +import { portManager } from '../../classes/port-manager/PortManager.js'; import { parseAutomationSettings } from '../automation/automation.parser.js'; +import { parseCustomFields } from '../custom-fields/customFields.parser.js'; import { parseProjectData } from '../project-data/projectData.parser.js'; import { parseRundowns } from '../rundown/rundown.parser.js'; import { parseSettings } from '../settings/settings.parser.js'; import { parseUrlPresets } from '../url-presets/urlPresets.parser.js'; import { parseViewSettings } from '../view-settings/viewSettings.parser.js'; -import { parseCustomFields } from '../custom-fields/customFields.parser.js'; import * as v3 from './migration/db.migration.v3.js'; import * as v4 from './migration/db.migration.v4.js'; -import { portManager } from '../../classes/port-manager/PortManager.js'; -import { getErrorMessage } from 'ontime-utils'; type ParsingError = { context: string; @@ -32,7 +31,6 @@ export function parseDatabaseModel( errors: ParsingError[]; migrated: boolean; } { - let migrated = false; let migratedData = jsonData; const errors: ParsingError[] = []; @@ -46,11 +44,9 @@ export function parseDatabaseModel( logger.error(LogOrigin.Server, 'Failed to migrate the data'); errors.push({ context: 'v3 migration', message: getErrorMessage(error) }); migratedData = jsonData; - }; - + } } - if (v4.shouldMigrateServerPort(migratedData)) { try { migrated = true; @@ -62,7 +58,6 @@ export function parseDatabaseModel( logger.error(LogOrigin.Server, 'Failed to migrate serverPort'); errors.push({ context: 'v4 migration', message: getErrorMessage(error) }); migratedData = jsonData; - } } diff --git a/apps/server/src/api-data/db/db.router.ts b/apps/server/src/api-data/db/db.router.ts index fba331346..3ce4b1d3f 100644 --- a/apps/server/src/api-data/db/db.router.ts +++ b/apps/server/src/api-data/db/db.router.ts @@ -16,11 +16,11 @@ import { } from './db.controller.js'; import { uploadProjectFile } from './db.middleware.js'; import { - validateNewProject, - validatePatchProject, validateFilenameBody, validateFilenameParam, validateNewFilenameBody, + validateNewProject, + validatePatchProject, validateQuickProject, } from './db.validation.js'; diff --git a/apps/server/src/api-data/db/db.validation.ts b/apps/server/src/api-data/db/db.validation.ts index 6ab75c7ef..40e91fdcd 100644 --- a/apps/server/src/api-data/db/db.validation.ts +++ b/apps/server/src/api-data/db/db.validation.ts @@ -1,5 +1,6 @@ import { body, param } from 'express-validator'; import sanitize from 'sanitize-filename'; + import { ensureJsonExtension } from '../../utils/fileManagement.js'; import { requestValidationFunction } from '../validation-utils/validationFunction.js'; diff --git a/apps/server/src/api-data/db/migration/db.migration.v3.ts b/apps/server/src/api-data/db/migration/db.migration.v3.ts index 599e40835..4a54cf685 100644 --- a/apps/server/src/api-data/db/migration/db.migration.v3.ts +++ b/apps/server/src/api-data/db/migration/db.migration.v3.ts @@ -5,8 +5,8 @@ import { EndAction, EntryCustomFields, NormalisedAutomation, - OntimeGroup, OntimeEntry, + OntimeGroup, ProjectData, ProjectRundowns, Rundown, @@ -19,15 +19,15 @@ import { Day, } from 'ontime-types'; import { - customFieldLabelToKey, checkRegex, + customFieldLabelToKey, + eventDef as eventModel, isKnownTimerType, validateEndAction, - eventDef as eventModel, } from 'ontime-utils'; -import { is } from '../../../utils/is.js'; import { getPartialProject } from '../../../models/dataModel.js'; +import { is } from '../../../utils/is.js'; // the methodology of the migrations is to just change the necessary keys to match with v4 // and then let the normal project parser handle ensuring the the file is correct diff --git a/apps/server/src/api-data/db/migration/db.migration.v4.ts b/apps/server/src/api-data/db/migration/db.migration.v4.ts index 143892cda..c3fcdb269 100644 --- a/apps/server/src/api-data/db/migration/db.migration.v4.ts +++ b/apps/server/src/api-data/db/migration/db.migration.v4.ts @@ -1,4 +1,5 @@ import { DatabaseModel, Settings } from 'ontime-types'; + import { is } from '../../../utils/is.js'; export function shouldMigrateServerPort(jsonData: object): boolean { diff --git a/apps/server/src/api-data/db/migration/migration.test.ts b/apps/server/src/api-data/db/migration/migration.test.ts index aa674f472..6a958c20e 100644 --- a/apps/server/src/api-data/db/migration/migration.test.ts +++ b/apps/server/src/api-data/db/migration/migration.test.ts @@ -1,6 +1,7 @@ import { AutomationSettings, CustomFields, + type Day, DatabaseModel, EndAction, OntimeView, @@ -8,12 +9,13 @@ import { Rundown, Settings, SupportedEntry, + TimeStrategy, TimerLifeCycle, TimerType, - TimeStrategy, URLPreset, ViewSettings, } from 'ontime-types'; + import * as v3 from './db.migration.v3.js'; import * as v4 from './db.migration.v4.js'; @@ -295,7 +297,7 @@ describe('v3 to v4', () => { flag: false, parent: null, delay: 0, - dayOffset: 0, + dayOffset: 0 as Day, gap: 0, }, group0: { @@ -340,7 +342,7 @@ describe('v3 to v4', () => { parent: 'group0', revision: -1, delay: 0, - dayOffset: 0, + dayOffset: 0 as Day, gap: 0, }, event3: { @@ -371,7 +373,7 @@ describe('v3 to v4', () => { parent: 'group0', revision: -1, delay: 0, - dayOffset: 0, + dayOffset: 0 as Day, gap: 0, }, group1: { diff --git a/apps/server/src/api-data/excel/__tests__/excel.parser.test.ts b/apps/server/src/api-data/excel/__tests__/excel.parser.test.ts index 0cf11ae88..52eba1c3e 100644 --- a/apps/server/src/api-data/excel/__tests__/excel.parser.test.ts +++ b/apps/server/src/api-data/excel/__tests__/excel.parser.test.ts @@ -1,10 +1,9 @@ import { CustomFields, OntimeEvent, OntimeGroup, SupportedEntry, TimerType } from 'ontime-types'; import { ImportMap, MILLIS_PER_MINUTE, millisToString } from 'ontime-utils'; -import { parseExcel } from '../excel.parser.js'; - -import { dataFromExcelTemplate } from './mockData.js'; import { simpleTemplate } from '../__mocks__/simpleTemplate.js'; +import { parseExcel } from '../excel.parser.js'; +import { dataFromExcelTemplate } from './mockData.js'; describe('parseExcel()', () => { it('parses the simple template file', () => { diff --git a/apps/server/src/api-data/excel/__tests__/excel.utils.test.ts b/apps/server/src/api-data/excel/__tests__/excel.utils.test.ts index 239bde956..8d56c002e 100644 --- a/apps/server/src/api-data/excel/__tests__/excel.utils.test.ts +++ b/apps/server/src/api-data/excel/__tests__/excel.utils.test.ts @@ -1,8 +1,7 @@ import { CustomFields } from 'ontime-types'; -import { defaultImportMap, ImportMap } from 'ontime-utils'; +import { ImportMap, defaultImportMap } from 'ontime-utils'; import { demoDb } from '../../../models/demoProject.js'; - import { getCustomFieldData, rundownToTabular } from '../excel.utils.js'; describe('getCustomFieldData()', () => { diff --git a/apps/server/src/api-data/excel/excel.middleware.ts b/apps/server/src/api-data/excel/excel.middleware.ts index 7feb85f37..241eee702 100644 --- a/apps/server/src/api-data/excel/excel.middleware.ts +++ b/apps/server/src/api-data/excel/excel.middleware.ts @@ -2,7 +2,6 @@ import type { Request } from 'express'; import multer, { type FileFilterCallback } from 'multer'; import { storage } from '../../utils/upload.js'; - import { EXCEL_MIME } from './excel.constants.js'; const filterExcel = (_req: Request, file: Express.Multer.File, cb: FileFilterCallback) => { diff --git a/apps/server/src/api-data/excel/excel.parser.ts b/apps/server/src/api-data/excel/excel.parser.ts index 476eddb8e..08b230eeb 100644 --- a/apps/server/src/api-data/excel/excel.parser.ts +++ b/apps/server/src/api-data/excel/excel.parser.ts @@ -1,14 +1,14 @@ import { CustomFields, - Rundown, + EntryCustomFields, + OntimeEntry, OntimeEvent, OntimeGroup, - EntryCustomFields, - SupportedEntry, - isOntimeGroup, - TimerType, OntimeMilestone, - OntimeEntry, + Rundown, + SupportedEntry, + TimerType, + isOntimeGroup, isOntimeMilestone, } from 'ontime-types'; import { @@ -16,16 +16,15 @@ import { defaultImportMap, generateId, isKnownTimerType, - validateTimerType, - validateEndAction, makeString, + validateEndAction, + validateTimerType, } from 'ontime-utils'; - import { Prettify } from 'ts-essentials'; import { is } from '../../utils/is.js'; import { parseExcelDate } from '../../utils/time.js'; -import { generateImportHandlers, getCustomFieldData, parseBooleanString, SheetMetadata } from './excel.utils.js'; +import { SheetMetadata, generateImportHandlers, getCustomFieldData, parseBooleanString } from './excel.utils.js'; type MergedOntimeEntry = Prettify< Omit & OntimeGroup, keyof OntimeMilestone> & OntimeMilestone, 'type'> & { diff --git a/apps/server/src/api-data/excel/excel.router.ts b/apps/server/src/api-data/excel/excel.router.ts index f69c20c1c..ffdc19e49 100644 --- a/apps/server/src/api-data/excel/excel.router.ts +++ b/apps/server/src/api-data/excel/excel.router.ts @@ -3,13 +3,11 @@ import type { Request, Response } from 'express'; import { CustomFields, ErrorResponse, Rundown, RundownSummary } from 'ontime-types'; import { getDataProvider } from '../../classes/data-provider/DataProvider.js'; - import { getProjectCustomFields } from '../rundown/rundown.dao.js'; - -import { uploadExcel } from './excel.middleware.js'; -import { validateFileExists, validateImportMapOptions, validateRundownExport } from './excel.validation.js'; -import { generateExcelFile, generateRundownPreview, readExcelFile } from './excel.service.js'; import { EXCEL_MIME } from './excel.constants.js'; +import { uploadExcel } from './excel.middleware.js'; +import { generateExcelFile, generateRundownPreview, readExcelFile } from './excel.service.js'; +import { validateFileExists, validateImportMapOptions, validateRundownExport } from './excel.validation.js'; export const router = express.Router(); diff --git a/apps/server/src/api-data/excel/excel.service.ts b/apps/server/src/api-data/excel/excel.service.ts index d3a47d8f1..b0085a150 100644 --- a/apps/server/src/api-data/excel/excel.service.ts +++ b/apps/server/src/api-data/excel/excel.service.ts @@ -3,20 +3,18 @@ * Google Sheets */ +import { existsSync } from 'fs'; +import { extname } from 'path'; + import { CustomFields, Rundown, RundownSummary } from 'ontime-types'; import { type ImportMap } from 'ontime-utils'; - -import { extname } from 'path'; -import { existsSync } from 'fs'; import xlsx from 'xlsx'; import type { WorkBook } from 'xlsx'; import { deleteFile } from '../../utils/fileManagement.js'; - -import { parseRundown } from '../rundown/rundown.parser.js'; -import { getProjectCustomFields, processRundown } from '../rundown/rundown.dao.js'; import { parseCustomFields } from '../custom-fields/customFields.parser.js'; - +import { getProjectCustomFields, processRundown } from '../rundown/rundown.dao.js'; +import { parseRundown } from '../rundown/rundown.parser.js'; import { parseExcel } from './excel.parser.js'; import { rundownToTabular } from './excel.utils.js'; diff --git a/apps/server/src/api-data/excel/excel.utils.ts b/apps/server/src/api-data/excel/excel.utils.ts index ac87becb5..8c3b175dd 100644 --- a/apps/server/src/api-data/excel/excel.utils.ts +++ b/apps/server/src/api-data/excel/excel.utils.ts @@ -1,5 +1,5 @@ import { CustomFieldKey, CustomFields, MaybeNumber, OntimeEntry, Rundown } from 'ontime-types'; -import { checkRegex, customFieldLabelToKey, ImportMap, millisToString } from 'ontime-utils'; +import { ImportMap, checkRegex, customFieldLabelToKey, millisToString } from 'ontime-utils'; /** * Receives an import map which contains custom field labels and a custom fields object diff --git a/apps/server/src/api-data/excel/excel.validation.ts b/apps/server/src/api-data/excel/excel.validation.ts index 84fa02f6c..fbed298d1 100644 --- a/apps/server/src/api-data/excel/excel.validation.ts +++ b/apps/server/src/api-data/excel/excel.validation.ts @@ -1,6 +1,5 @@ -import { isImportMap } from 'ontime-utils'; - import { body, param } from 'express-validator'; +import { isImportMap } from 'ontime-utils'; import { requestValidationFunction, diff --git a/apps/server/src/api-data/index.ts b/apps/server/src/api-data/index.ts index 388bdf92f..4f7936d8e 100644 --- a/apps/server/src/api-data/index.ts +++ b/apps/server/src/api-data/index.ts @@ -1,18 +1,18 @@ import express from 'express'; +import { router as assetsRouter } from './assets/assets.router.js'; import { router as automationsRouter } from './automation/automation.router.js'; -import { router as urlPresetsRouter } from './url-presets/urlPresets.router.js'; import { router as customFieldsRouter } from './custom-fields/customFields.router.js'; import { router as dbRouter } from './db/db.router.js'; +import { router as excelRouter } from './excel/excel.router.js'; import { router as projectRouter } from './project-data/projectData.router.js'; +import { router as reportRouter } from './report/report.router.js'; import { router as rundownsRouter } from './rundown/rundown.router.js'; +import { router as sessionRouter } from './session/session.router.js'; import { router as settingsRouter } from './settings/settings.router.js'; import { router as sheetsRouter } from './sheets/sheets.router.js'; -import { router as excelRouter } from './excel/excel.router.js'; -import { router as sessionRouter } from './session/session.router.js'; +import { router as urlPresetsRouter } from './url-presets/urlPresets.router.js'; import { router as viewSettingsRouter } from './view-settings/viewSettings.router.js'; -import { router as reportRouter } from './report/report.router.js'; -import { router as assetsRouter } from './assets/assets.router.js'; export const appRouter = express.Router(); diff --git a/apps/server/src/api-data/project-data/projectData.dao.ts b/apps/server/src/api-data/project-data/projectData.dao.ts index 97c1f8dcd..24ef79be5 100644 --- a/apps/server/src/api-data/project-data/projectData.dao.ts +++ b/apps/server/src/api-data/project-data/projectData.dao.ts @@ -1,10 +1,11 @@ +import { join } from 'node:path'; + import { ProjectData, RefetchKey } from 'ontime-types'; -import { getDataProvider } from '../../classes/data-provider/DataProvider.js'; -import { join } from 'node:path'; -import { deleteFile } from '../../utils/fileManagement.js'; -import { publicDir } from '../../setup/index.js'; import { sendRefetch } from '../../adapters/WebsocketAdapter.js'; +import { getDataProvider } from '../../classes/data-provider/DataProvider.js'; +import { publicDir } from '../../setup/index.js'; +import { deleteFile } from '../../utils/fileManagement.js'; /** * Gets the stored project data diff --git a/apps/server/src/api-data/project-data/projectData.parser.ts b/apps/server/src/api-data/project-data/projectData.parser.ts index 5357aaa7f..73ff787cd 100644 --- a/apps/server/src/api-data/project-data/projectData.parser.ts +++ b/apps/server/src/api-data/project-data/projectData.parser.ts @@ -1,7 +1,7 @@ import { DatabaseModel, ProjectData } from 'ontime-types'; -import { ErrorEmitter } from '../../utils/parserUtils.js'; import { getPartialProject } from '../../models/dataModel.js'; +import { ErrorEmitter } from '../../utils/parserUtils.js'; /** * Parse event portion of an entry diff --git a/apps/server/src/api-data/project-data/projectData.router.ts b/apps/server/src/api-data/project-data/projectData.router.ts index 45c6597a9..4e2951951 100644 --- a/apps/server/src/api-data/project-data/projectData.router.ts +++ b/apps/server/src/api-data/project-data/projectData.router.ts @@ -3,11 +3,11 @@ import type { Request, Response } from 'express'; import type { ErrorResponse, ProjectData } from 'ontime-types'; import { getErrorMessage } from 'ontime-utils'; -import { projectSanitiser } from './projectData.validation.js'; -import { uploadImageFile } from '../db/db.middleware.js'; -import { postProjectLogo } from '../db/db.controller.js'; -import * as projectDao from './projectData.dao.js'; import { removeUndefined } from '../../utils/parserUtils.js'; +import { postProjectLogo } from '../db/db.controller.js'; +import { uploadImageFile } from '../db/db.middleware.js'; +import * as projectDao from './projectData.dao.js'; +import { projectSanitiser } from './projectData.validation.js'; export const router = express.Router(); diff --git a/apps/server/src/api-data/project-data/projectData.validation.ts b/apps/server/src/api-data/project-data/projectData.validation.ts index 272efe471..3f337d45e 100644 --- a/apps/server/src/api-data/project-data/projectData.validation.ts +++ b/apps/server/src/api-data/project-data/projectData.validation.ts @@ -1,4 +1,5 @@ import { body } from 'express-validator'; + import { requestValidationFunction } from '../validation-utils/validationFunction.js'; export const projectSanitiser = [ diff --git a/apps/server/src/api-data/report/report.router.ts b/apps/server/src/api-data/report/report.router.ts index 2d6ad3736..62864c033 100644 --- a/apps/server/src/api-data/report/report.router.ts +++ b/apps/server/src/api-data/report/report.router.ts @@ -1,5 +1,6 @@ import express from 'express'; import type { Request, Response } from 'express'; + import { paramsWithId } from '../validation-utils/validationFunction.js'; import * as report from './report.service.js'; diff --git a/apps/server/src/api-data/report/report.service.ts b/apps/server/src/api-data/report/report.service.ts index 62e860c28..f774bfe03 100644 --- a/apps/server/src/api-data/report/report.service.ts +++ b/apps/server/src/api-data/report/report.service.ts @@ -1,7 +1,8 @@ -import { OntimeReport, OntimeEventReport, TimerLifeCycle, RefetchKey } from 'ontime-types'; -import { RuntimeState } from '../../stores/runtimeState.js'; +import { OntimeEventReport, OntimeReport, RefetchKey, TimerLifeCycle } from 'ontime-types'; import { DeepReadonly } from 'ts-essentials'; + import { sendRefetch } from '../../adapters/WebsocketAdapter.js'; +import { RuntimeState } from '../../stores/runtimeState.js'; const report = new Map(); diff --git a/apps/server/src/api-data/rundown/__mocks__/rundown.mocks.ts b/apps/server/src/api-data/rundown/__mocks__/rundown.mocks.ts index ea96d9092..394556d81 100644 --- a/apps/server/src/api-data/rundown/__mocks__/rundown.mocks.ts +++ b/apps/server/src/api-data/rundown/__mocks__/rundown.mocks.ts @@ -1,11 +1,11 @@ import { - SupportedEntry, - OntimeEvent, - OntimeDelay, - OntimeGroup, - Rundown, CustomField, + OntimeDelay, + OntimeEvent, + OntimeGroup, OntimeMilestone, + Rundown, + SupportedEntry, } from 'ontime-types'; import { makeNewRundown } from '../../../models/dataModel.js'; diff --git a/apps/server/src/api-data/rundown/__tests__/rundown.dao.test.ts b/apps/server/src/api-data/rundown/__tests__/rundown.dao.test.ts index 3bc0ad4bd..aae0b3a63 100644 --- a/apps/server/src/api-data/rundown/__tests__/rundown.dao.test.ts +++ b/apps/server/src/api-data/rundown/__tests__/rundown.dao.test.ts @@ -1,23 +1,24 @@ import { + type Day, CustomFields, - OntimeGroup, OntimeDelay, OntimeEvent, + OntimeGroup, + OntimeMilestone, SupportedEntry, TimeStrategy, - OntimeMilestone, } from 'ontime-types'; -import { dayInMs, MILLIS_PER_HOUR, MILLIS_PER_MINUTE } from 'ontime-utils'; +import { MILLIS_PER_HOUR, MILLIS_PER_MINUTE, dayInMs } from 'ontime-utils'; +import { demoDb } from '../../../models/demoProject.js'; import { - makeOntimeEvent, - makeRundown, - makeOntimeGroup, - makeOntimeDelay, makeCustomField, + makeOntimeDelay, + makeOntimeEvent, + makeOntimeGroup, makeOntimeMilestone, + makeRundown, } from '../__mocks__/rundown.mocks.js'; - import { createTransaction, customFieldMutation, @@ -25,23 +26,20 @@ import { rundownCache, rundownMutation, } from '../rundown.dao.js'; -import { demoDb } from '../../../models/demoProject.js'; import { type ProcessedRundownMetadata } from '../rundown.parser.js'; const setRundownMock = vi.fn(); const setCustomFieldsMock = vi.fn(); -beforeAll(() => { - vi.mock('../../../classes/data-provider/DataProvider.js', () => { - return { - getDataProvider: vi.fn().mockImplementation(() => { - return { - setRundown: setRundownMock, - setCustomFields: setCustomFieldsMock, - }; - }), - }; - }); +vi.mock('../../../classes/data-provider/DataProvider.js', () => { + return { + getDataProvider: vi.fn().mockImplementation(() => { + return { + setRundown: setRundownMock, + setCustomFields: setCustomFieldsMock, + }; + }), + }; }); afterAll(() => { @@ -100,6 +98,7 @@ describe('processRundown()', () => { Object.keys(result?.entries ?? {}).length, 'events', ); + expect(t2 - t1).lessThan(100); }); it('generates metadata from given rundown', () => { @@ -1345,7 +1344,7 @@ describe('rundownMutation.applyDelay()', () => { '1': makeOntimeEvent({ id: '1', gap: 0, - dayOffset: 0, + dayOffset: 0 as Day, timeStart: 46800000, // 13:00:00 timeEnd: 50400000, // 14:00:00 duration: MILLIS_PER_HOUR, @@ -1354,7 +1353,7 @@ describe('rundownMutation.applyDelay()', () => { '2': makeOntimeEvent({ id: '2', gap: 1 * MILLIS_PER_HOUR, - dayOffset: 0, + dayOffset: 0 as Day, timeStart: 54000000, // 15:00:00 timeEnd: 57600000, // 16:00:00 duration: MILLIS_PER_HOUR, diff --git a/apps/server/src/api-data/rundown/__tests__/rundown.parser.test.ts b/apps/server/src/api-data/rundown/__tests__/rundown.parser.test.ts index 35ceb2058..04cc2b7f2 100644 --- a/apps/server/src/api-data/rundown/__tests__/rundown.parser.test.ts +++ b/apps/server/src/api-data/rundown/__tests__/rundown.parser.test.ts @@ -1,9 +1,8 @@ -import { SupportedEntry, OntimeEvent, OntimeGroup, Rundown, CustomFields } from 'ontime-types'; +import { CustomFields, OntimeEvent, OntimeGroup, Rundown, SupportedEntry } from 'ontime-types'; import { makeNewRundown } from '../../../models/dataModel.js'; - -import { makeOntimeGroup, makeOntimeEvent, makeOntimeMilestone } from '../__mocks__/rundown.mocks.js'; -import { parseRundowns, parseRundown, sanitiseCustomFields } from '../rundown.parser.js'; +import { makeOntimeEvent, makeOntimeGroup, makeOntimeMilestone } from '../__mocks__/rundown.mocks.js'; +import { parseRundown, parseRundowns, sanitiseCustomFields } from '../rundown.parser.js'; describe('parseRundowns()', () => { it('returns a default project rundown if nothing is given', () => { diff --git a/apps/server/src/api-data/rundown/__tests__/rundown.utils.test.ts b/apps/server/src/api-data/rundown/__tests__/rundown.utils.test.ts index e344afcdd..5a16c8930 100644 --- a/apps/server/src/api-data/rundown/__tests__/rundown.utils.test.ts +++ b/apps/server/src/api-data/rundown/__tests__/rundown.utils.test.ts @@ -1,10 +1,9 @@ -import { TimeStrategy, EndAction, TimerType, OntimeEvent } from 'ontime-types'; -import { createEvent, MILLIS_PER_HOUR } from 'ontime-utils'; - +import { EndAction, OntimeEvent, TimeStrategy, TimerType } from 'ontime-types'; +import { MILLIS_PER_HOUR, createEvent } from 'ontime-utils'; import { assertType } from 'vitest'; import { demoDb } from '../../../models/demoProject.js'; - +import { makeOntimeEvent, makeOntimeGroup, makeRundown } from '../__mocks__/rundown.mocks.js'; import { calculateDayOffset, deleteById, @@ -13,7 +12,6 @@ import { hasChanges, makeDeepClone, } from '../rundown.utils.js'; -import { makeOntimeGroup, makeOntimeEvent, makeRundown } from '../__mocks__/rundown.mocks.js'; describe('test event validator', () => { it('validates a good object', () => { diff --git a/apps/server/src/api-data/rundown/rundown.dao.ts b/apps/server/src/api-data/rundown/rundown.dao.ts index 775e4d247..456ed0a51 100644 --- a/apps/server/src/api-data/rundown/rundown.dao.ts +++ b/apps/server/src/api-data/rundown/rundown.dao.ts @@ -15,22 +15,22 @@ import { CustomFieldKey, CustomFields, EntryId, - isOntimeGroup, - isOntimeEvent, - isPlayableEvent, - OntimeGroup, + InsertOptions, OntimeDelay, OntimeEntry, OntimeEvent, + OntimeGroup, PatchWithId, Rundown, - InsertOptions, + isOntimeEvent, + isOntimeGroup, + isPlayableEvent, } from 'ontime-types'; -import { addToRundown, customFieldLabelToKey, getInsertAfterId, insertAtIndex, createGroup } from 'ontime-utils'; +import { addToRundown, createGroup, customFieldLabelToKey, getInsertAfterId, insertAtIndex } from 'ontime-utils'; import { getDataProvider } from '../../classes/data-provider/DataProvider.js'; import { consoleError } from '../../utils/console.js'; - +import { ProcessedRundownMetadata, makeRundownMetadata } from './rundown.parser.js'; import type { RundownMetadata } from './rundown.types.js'; import { applyPatchToEntry, @@ -40,7 +40,6 @@ import { getUniqueId, makeDeepClone, } from './rundown.utils.js'; -import { makeRundownMetadata, ProcessedRundownMetadata } from './rundown.parser.js'; /** * The currently loaded rundown in cache diff --git a/apps/server/src/api-data/rundown/rundown.parser.ts b/apps/server/src/api-data/rundown/rundown.parser.ts index b7069d2b2..332ed29c7 100644 --- a/apps/server/src/api-data/rundown/rundown.parser.ts +++ b/apps/server/src/api-data/rundown/rundown.parser.ts @@ -1,40 +1,39 @@ import { - DatabaseModel, - CustomFields, - ProjectRundowns, - Rundown, - OntimeEvent, - isOntimeEvent, - isOntimeDelay, - isOntimeGroup, CustomFieldKey, + CustomFields, + DatabaseModel, + Day, EntryId, OntimeEntry, - PlayableEvent, - RundownEntries, - isPlayableEvent, - isOntimeMilestone, - OntimeMilestone, + OntimeEvent, OntimeGroup, - Day, + OntimeMilestone, + PlayableEvent, + ProjectRundowns, + Rundown, + RundownEntries, + isOntimeDelay, + isOntimeEvent, + isOntimeGroup, + isOntimeMilestone, + isPlayableEvent, } from 'ontime-types'; import { - isObjectEmpty, - generateId, - getLinkedTimes, - getTimeFrom, - isNewLatest, createDelay, createEvent, createGroup, createMilestone, + generateId, + getLinkedTimes, + getTimeFrom, + isNewLatest, + isObjectEmpty, } from 'ontime-utils'; import { makeNewRundown } from '../../models/dataModel.js'; import type { ErrorEmitter } from '../../utils/parserUtils.js'; - -import { calculateDayOffset, cleanupCustomFields } from './rundown.utils.js'; import { RundownMetadata } from './rundown.types.js'; +import { calculateDayOffset, cleanupCustomFields } from './rundown.utils.js'; /** * Parse a rundowns object along with the project custom fields diff --git a/apps/server/src/api-data/rundown/rundown.router.ts b/apps/server/src/api-data/rundown/rundown.router.ts index fbb8ebcc4..996900c59 100644 --- a/apps/server/src/api-data/rundown/rundown.router.ts +++ b/apps/server/src/api-data/rundown/rundown.router.ts @@ -1,14 +1,11 @@ +import type { Request, Response } from 'express'; +import express from 'express'; import { ErrorResponse, OntimeEntry, ProjectRundownsList, Rundown } from 'ontime-types'; import { getErrorMessage } from 'ontime-utils'; -import type { Request, Response } from 'express'; -import express from 'express'; - import { getDataProvider } from '../../classes/data-provider/DataProvider.js'; import { makeNewRundown } from '../../models/dataModel.js'; - import { paramsWithId } from '../validation-utils/validationFunction.js'; - import { getCurrentRundown } from './rundown.dao.js'; import { addEntry, @@ -20,23 +17,23 @@ import { editEntry, groupEntries, initRundown, + loadRundown, reorderEntry, swapEvents, - loadRundown, ungroupEntries, } from './rundown.service.js'; +import { duplicateRundown, normalisedToRundownArray } from './rundown.utils.js'; import { - rundownArrayOfIds, + clonePostValidator, entryBatchPutValidator, entryPostValidator, - rundownPostValidator, entryPutValidator, entryReorderValidator, entrySwapValidator, + rundownArrayOfIds, + rundownPostValidator, validateRundownMutation, - clonePostValidator, } from './rundown.validation.js'; -import { duplicateRundown, normalisedToRundownArray } from './rundown.utils.js'; export const router = express.Router(); diff --git a/apps/server/src/api-data/rundown/rundown.service.ts b/apps/server/src/api-data/rundown/rundown.service.ts index a5f61bee7..48a8873e5 100644 --- a/apps/server/src/api-data/rundown/rundown.service.ts +++ b/apps/server/src/api-data/rundown/rundown.service.ts @@ -4,26 +4,26 @@ import { CustomFields, EntryId, EventPostPayload, - isOntimeGroup, - isOntimeDelay, - isOntimeEvent, - OntimeGroup, + InsertOptions, + LogOrigin, OntimeEntry, + OntimeGroup, PatchWithId, + ProjectRundowns, RefetchKey, Rundown, - LogOrigin, - ProjectRundowns, - InsertOptions, + isOntimeDelay, + isOntimeEvent, + isOntimeGroup, } from 'ontime-types'; import { customFieldLabelToKey, getInsertAfterId, resolveInsertParent } from 'ontime-utils'; -import { updateRundownData } from '../../stores/runtimeState.js'; -import { runtimeService } from '../../services/runtime-service/runtime.service.js'; import { sendRefetch } from '../../adapters/WebsocketAdapter.js'; -import { setLastLoadedRundown } from '../../services/app-state-service/AppStateService.js'; +import { getDataProvider } from '../../classes/data-provider/DataProvider.js'; import { logger } from '../../classes/Logger.js'; - +import { setLastLoadedRundown } from '../../services/app-state-service/AppStateService.js'; +import { runtimeService } from '../../services/runtime-service/runtime.service.js'; +import { updateRundownData } from '../../stores/runtimeState.js'; import { createTransaction, customFieldMutation, @@ -34,7 +34,6 @@ import { } from './rundown.dao.js'; import type { RundownMetadata } from './rundown.types.js'; import { generateEvent, hasChanges } from './rundown.utils.js'; -import { getDataProvider } from '../../classes/data-provider/DataProvider.js'; /** * creates a new entry with given data diff --git a/apps/server/src/api-data/rundown/rundown.utils.ts b/apps/server/src/api-data/rundown/rundown.utils.ts index 811402e27..84ae435eb 100644 --- a/apps/server/src/api-data/rundown/rundown.utils.ts +++ b/apps/server/src/api-data/rundown/rundown.utils.ts @@ -2,30 +2,30 @@ import { CustomFields, EntryCustomFields, EntryId, - isOntimeGroup, - isOntimeDelay, - isOntimeEvent, - isOntimeMilestone, OntimeBaseEvent, - OntimeGroup, OntimeDelay, OntimeEntry, OntimeEvent, + OntimeGroup, OntimeMilestone, + ProjectRundown, + ProjectRundowns, Rundown, SupportedEntry, TimeStrategy, - ProjectRundown, - ProjectRundowns, + isOntimeDelay, + isOntimeEvent, + isOntimeGroup, + isOntimeMilestone, } from 'ontime-types'; import { - dayInMs, - generateId, - getCueCandidate, createDelay, createEvent, createGroup, createMilestone, + dayInMs, + generateId, + getCueCandidate, makeString, validateEndAction, validateTimerType, diff --git a/apps/server/src/api-data/rundown/rundown.validation.ts b/apps/server/src/api-data/rundown/rundown.validation.ts index 2e0997a48..4d0d0d946 100644 --- a/apps/server/src/api-data/rundown/rundown.validation.ts +++ b/apps/server/src/api-data/rundown/rundown.validation.ts @@ -1,4 +1,4 @@ -import type { Request, Response, NextFunction } from 'express'; +import type { NextFunction, Request, Response } from 'express'; import { body, param } from 'express-validator'; import { requestValidationFunction } from '../validation-utils/validationFunction.js'; diff --git a/apps/server/src/api-data/session/session.router.ts b/apps/server/src/api-data/session/session.router.ts index 743b2859f..d4f98c7dd 100644 --- a/apps/server/src/api-data/session/session.router.ts +++ b/apps/server/src/api-data/session/session.router.ts @@ -1,9 +1,10 @@ import express from 'express'; import type { Request, Response } from 'express'; -import { getErrorMessage } from 'ontime-utils'; import type { ErrorResponse, GetInfo, GetUrl, SessionStats } from 'ontime-types'; -import { validateGenerateUrl } from './session.validation.js'; +import { getErrorMessage } from 'ontime-utils'; + import * as sessionService from './session.service.js'; +import { validateGenerateUrl } from './session.validation.js'; export const router = express.Router(); diff --git a/apps/server/src/api-data/session/session.service.ts b/apps/server/src/api-data/session/session.service.ts index 16d2f9f72..884b0cee9 100644 --- a/apps/server/src/api-data/session/session.service.ts +++ b/apps/server/src/api-data/session/session.service.ts @@ -1,17 +1,17 @@ import { GetInfo, LinkOptions, OntimeView, SessionStats } from 'ontime-types'; -import { getDataProvider } from '../../classes/data-provider/DataProvider.js'; -import { publicDir } from '../../setup/index.js'; import { socket } from '../../adapters/WebsocketAdapter.js'; import { getLastRequest } from '../../api-integration/integration.controller.js'; +import { getDataProvider } from '../../classes/data-provider/DataProvider.js'; +import { portManager } from '../../classes/port-manager/PortManager.js'; +import { password, routerPrefix } from '../../externals.js'; +import { ONTIME_VERSION } from '../../ONTIME_VERSION.js'; import { getCurrentProject } from '../../services/project-service/ProjectService.js'; import { runtimeService } from '../../services/runtime-service/runtime.service.js'; +import { publicDir } from '../../setup/index.js'; +import { hashPassword } from '../../utils/hash.js'; import { getNetworkInterfaces } from '../../utils/network.js'; import { getTimezoneLabel } from '../../utils/time.js'; -import { password, routerPrefix } from '../../externals.js'; -import { hashPassword } from '../../utils/hash.js'; -import { ONTIME_VERSION } from '../../ONTIME_VERSION.js'; -import { portManager } from '../../classes/port-manager/PortManager.js'; const startedAt = new Date(); diff --git a/apps/server/src/api-data/session/session.validation.ts b/apps/server/src/api-data/session/session.validation.ts index 68509e9b1..a87d25cd4 100644 --- a/apps/server/src/api-data/session/session.validation.ts +++ b/apps/server/src/api-data/session/session.validation.ts @@ -1,4 +1,5 @@ import { body } from 'express-validator'; + import { requestValidationFunction } from '../validation-utils/validationFunction.js'; export const validateGenerateUrl = [ diff --git a/apps/server/src/api-data/settings/__tests__/settings.parser.test.ts b/apps/server/src/api-data/settings/__tests__/settings.parser.test.ts index 995bb0af2..de7d3f610 100644 --- a/apps/server/src/api-data/settings/__tests__/settings.parser.test.ts +++ b/apps/server/src/api-data/settings/__tests__/settings.parser.test.ts @@ -4,7 +4,7 @@ import { parseSettings } from '../settings.parser.js'; describe('parseSettings()', () => { it('throws if settings object does not exist', () => { - expect(() => parseSettings({})).toThrow(); + expect(() => parseSettings({})).toThrow('ERROR: unable to parse settings, missing or incorrect version'); }); it('returns an a base model as long as we have the app version', () => { diff --git a/apps/server/src/api-data/settings/settings.router.ts b/apps/server/src/api-data/settings/settings.router.ts index eaf140f16..767c72e06 100644 --- a/apps/server/src/api-data/settings/settings.router.ts +++ b/apps/server/src/api-data/settings/settings.router.ts @@ -1,29 +1,24 @@ -import express from "express"; -import { matchedData } from "express-validator"; -import type { Request, Response } from "express"; -import { deepEqual } from "fast-equals"; +import express from 'express'; +import type { Request, Response } from 'express'; +import { matchedData } from 'express-validator'; +import { deepEqual } from 'fast-equals'; +import { ErrorResponse, PortInfo, RefetchKey, Settings } from 'ontime-types'; +import { getErrorMessage, obfuscate } from 'ontime-utils'; -import { ErrorResponse, PortInfo, RefetchKey, Settings } from "ontime-types"; -import { getErrorMessage, obfuscate } from "ontime-utils"; - -import { - validateSettings, - validateWelcomeDialog, - validateServerPort, -} from "./settings.validation.js"; -import { getDataProvider } from "../../classes/data-provider/DataProvider.js"; -import * as appState from "../../services/app-state-service/AppStateService.js"; -import { sendRefetch } from "../../adapters/WebsocketAdapter.js"; -import { portManager } from "../../classes/port-manager/PortManager.js"; +import { sendRefetch } from '../../adapters/WebsocketAdapter.js'; +import { getDataProvider } from '../../classes/data-provider/DataProvider.js'; +import { portManager } from '../../classes/port-manager/PortManager.js'; +import * as appState from '../../services/app-state-service/AppStateService.js'; +import { validateSettings, validateWelcomeDialog, validateServerPort } from './settings.validation.js'; export const router = express.Router(); -router.post("/welcomedialog", validateWelcomeDialog, async (req: Request, res: Response) => { +router.post('/welcomedialog', validateWelcomeDialog, async (req: Request, res: Response) => { const show = await appState.setShowWelcomeDialog(req.body.show); res.status(200).json({ show }); }); -router.get("/", (_req: Request, res: Response) => { +router.get('/', (_req: Request, res: Response) => { const settings = getDataProvider().getSettings(); const obfuscatedSettings = { ...settings }; if (settings.editorKey) { @@ -37,30 +32,26 @@ router.get("/", (_req: Request, res: Response) => { res.status(200).json(obfuscatedSettings); }); -router.post( - "/", - validateSettings, - async (req: Request, res: Response) => { - try { - const data = matchedData(req); - const settings = getDataProvider().getSettings(); +router.post('/', validateSettings, async (req: Request, res: Response) => { + try { + const data = matchedData(req); + const settings = getDataProvider().getSettings(); - data.version = settings.version; + data.version = settings.version; - if (!deepEqual(data, settings)) { - await getDataProvider().setSettings(data); - sendRefetch(RefetchKey.Settings); - } - - res.status(200).json(data); - } catch (error) { - const message = getErrorMessage(error); - res.status(400).json({ message }); + if (!deepEqual(data, settings)) { + await getDataProvider().setSettings(data); + sendRefetch(RefetchKey.Settings); } - }, -); -router.get("/serverport", (_req: Request, res: Response) => { + res.status(200).json(data); + } catch (error) { + const message = getErrorMessage(error); + res.status(400).json({ message }); + } +}); + +router.get('/serverport', (_req: Request, res: Response) => { try { const { port, pendingRestart } = portManager.getPort(); res.status(200).json({ port, pendingRestart }); @@ -70,19 +61,15 @@ router.get("/serverport", (_req: Request, res: Response) => { - try { - const { serverPort } = matchedData<{ serverPort: number }>(req); - portManager.changePort(serverPort); - const { port, pendingRestart } = portManager.getPort(); +router.post('/serverport', validateServerPort, async (req: Request, res: Response) => { + try { + const { serverPort } = matchedData<{ serverPort: number }>(req); + portManager.changePort(serverPort); + const { port, pendingRestart } = portManager.getPort(); - res.status(200).json({ port, pendingRestart }); - } catch (error) { - const message = getErrorMessage(error); - res.status(400).json({ message }); - } - }, -); + res.status(200).json({ port, pendingRestart }); + } catch (error) { + const message = getErrorMessage(error); + res.status(400).json({ message }); + } +}); diff --git a/apps/server/src/api-data/settings/settings.validation.ts b/apps/server/src/api-data/settings/settings.validation.ts index 0e8881fd9..780990118 100644 --- a/apps/server/src/api-data/settings/settings.validation.ts +++ b/apps/server/src/api-data/settings/settings.validation.ts @@ -1,4 +1,5 @@ import { body } from 'express-validator'; + import { requestValidationFunction } from '../validation-utils/validationFunction.js'; /** diff --git a/apps/server/src/api-data/sheets/__tests__/sheet.utils.test.ts b/apps/server/src/api-data/sheets/__tests__/sheet.utils.test.ts index 70b417f99..f46ca49ae 100644 --- a/apps/server/src/api-data/sheets/__tests__/sheet.utils.test.ts +++ b/apps/server/src/api-data/sheets/__tests__/sheet.utils.test.ts @@ -1,7 +1,7 @@ -import { EndAction, OntimeEvent, SupportedEntry, TimeStrategy, TimerType } from 'ontime-types'; +import { type Day, EndAction, OntimeEvent, SupportedEntry, TimeStrategy, TimerType } from 'ontime-types'; import { millisToString } from 'ontime-utils'; -import { getA1Notation, cellRequestFromEvent } from '../sheets.utils.js'; +import { cellRequestFromEvent, getA1Notation } from '../sheets.utils.js'; describe('getA1Notation()', () => { test('A1', () => { @@ -38,7 +38,7 @@ describe('cellRequestFromEvent()', () => { colour: 'red', delay: 0, gap: 0, - dayOffset: 0, + dayOffset: 0 as Day, parent: null, revision: 0, id: '1358', @@ -89,7 +89,7 @@ describe('cellRequestFromEvent()', () => { revision: 0, delay: 0, gap: 0, - dayOffset: 0, + dayOffset: 0 as Day, id: '1358', timeWarning: 0, timeDanger: 0, @@ -140,7 +140,7 @@ describe('cellRequestFromEvent()', () => { revision: 0, delay: 0, gap: 0, - dayOffset: 0, + dayOffset: 0 as Day, id: '1358', timeWarning: 0, timeDanger: 0, @@ -187,7 +187,7 @@ describe('cellRequestFromEvent()', () => { colour: 'red', delay: 0, gap: 0, - dayOffset: 0, + dayOffset: 0 as Day, parent: null, revision: 0, id: '1358', @@ -226,7 +226,7 @@ describe('cellRequestFromEvent()', () => { revision: 0, delay: 0, gap: 0, - dayOffset: 0, + dayOffset: 0 as Day, id: '1358', timeWarning: 0, timeDanger: 0, @@ -264,7 +264,7 @@ describe('cellRequestFromEvent()', () => { revision: 0, delay: 0, gap: 0, - dayOffset: 0, + dayOffset: 0 as Day, id: '1358', timeWarning: 0, timeDanger: 0, diff --git a/apps/server/src/api-data/sheets/sheets.controller.ts b/apps/server/src/api-data/sheets/sheets.controller.ts index 8ce472f64..e4cfcc27f 100644 --- a/apps/server/src/api-data/sheets/sheets.controller.ts +++ b/apps/server/src/api-data/sheets/sheets.controller.ts @@ -3,22 +3,21 @@ * Google Sheets */ +import { readFileSync } from 'fs'; + +import { Request, Response } from 'express'; import type { AuthenticationStatus, CustomFields, ErrorResponse, Rundown, RundownSummary } from 'ontime-types'; import { getErrorMessage } from 'ontime-utils'; -import { Request, Response } from 'express'; -import { readFileSync } from 'fs'; - import { deleteFile } from '../../utils/fileManagement.js'; - import { - revoke, + download, + getWorksheetOptions, handleClientSecret, handleInitialConnection, hasAuth, - download, + revoke, upload, - getWorksheetOptions, } from './sheets.service.js'; export async function requestConnection( diff --git a/apps/server/src/api-data/sheets/sheets.service.ts b/apps/server/src/api-data/sheets/sheets.service.ts index aa16725d5..ca59a2f7d 100644 --- a/apps/server/src/api-data/sheets/sheets.service.ts +++ b/apps/server/src/api-data/sheets/sheets.service.ts @@ -4,35 +4,32 @@ * @link https://developers.google.com/identity/protocols/oauth2/limited-input-device */ +import { sheets, type sheets_v4 } from '@googleapis/sheets'; +import { Credentials, OAuth2Client } from 'google-auth-library'; import { AuthenticationStatus, CustomFields, DatabaseModel, EntryId, - isOntimeEvent, - isOntimeMilestone, LogOrigin, MaybeString, OntimeGroup, Rundown, RundownSummary, SupportedEntry, + isOntimeEvent, + isOntimeMilestone, } from 'ontime-types'; import { ImportMap, getErrorMessage } from 'ontime-utils'; -import { sheets, type sheets_v4 } from '@googleapis/sheets'; -import { Credentials, OAuth2Client } from 'google-auth-library'; - import { logger } from '../../classes/Logger.js'; -import { parseRundowns } from '../rundown/rundown.parser.js'; - -import { getCurrentRundown, getProjectCustomFields, processRundown } from '../rundown/rundown.dao.js'; -import { parseExcel } from '../excel/excel.parser.js'; -import { parseCustomFields } from '../custom-fields/customFields.parser.js'; import { consoleSubdued } from '../../utils/console.js'; - -import { cellRequestFromEvent, type ClientSecret, getA1Notation, isClientSecret } from './sheets.utils.js'; +import { parseCustomFields } from '../custom-fields/customFields.parser.js'; +import { parseExcel } from '../excel/excel.parser.js'; +import { getCurrentRundown, getProjectCustomFields, processRundown } from '../rundown/rundown.dao.js'; +import { parseRundowns } from '../rundown/rundown.parser.js'; import { catchCommonImportXlsxError } from './googleApi.utils.js'; +import { type ClientSecret, cellRequestFromEvent, getA1Notation, isClientSecret } from './sheets.utils.js'; const sheetScope = 'https://www.googleapis.com/auth/spreadsheets'; const codesUrl = 'https://oauth2.googleapis.com/device/code'; diff --git a/apps/server/src/api-data/sheets/sheets.utils.ts b/apps/server/src/api-data/sheets/sheets.utils.ts index 44ad69599..516613ac9 100644 --- a/apps/server/src/api-data/sheets/sheets.utils.ts +++ b/apps/server/src/api-data/sheets/sheets.utils.ts @@ -1,15 +1,14 @@ +import type { sheets_v4 } from '@googleapis/sheets'; import { OntimeEntry, + OntimeEntryCommonKeys, RGBColour, isOntimeDelay, - OntimeEntryCommonKeys, isOntimeGroup, isOntimeMilestone, } from 'ontime-types'; import { cssOrHexToColour, isLightColour, millisToString, mixColours } from 'ontime-utils'; -import type { sheets_v4 } from '@googleapis/sheets'; - import { is } from '../../utils/is.js'; export type ClientSecret = { @@ -104,6 +103,7 @@ export function cellRequestFromEvent( const thisCol = e[1].col; const diff = thisCol - prevCol; if (diff > 1) { + // TODO: we need to clarify this logic const fillArr = new Array<(typeof rowData)[0]>(1).fill(['blank', { row: e[1].row, col: prevCol + 1 }]); rowData.splice(index, 0, ...fillArr); } diff --git a/apps/server/src/api-data/sheets/sheets.validation.ts b/apps/server/src/api-data/sheets/sheets.validation.ts index bf687c8fb..62aea3526 100644 --- a/apps/server/src/api-data/sheets/sheets.validation.ts +++ b/apps/server/src/api-data/sheets/sheets.validation.ts @@ -1,7 +1,7 @@ +import { NextFunction, Request, Response } from 'express'; +import { body, param, validationResult } from 'express-validator'; import { isImportMap } from 'ontime-utils'; -import { body, param, validationResult } from 'express-validator'; -import { NextFunction, Request, Response } from 'express'; import { requestValidationFunction } from '../validation-utils/validationFunction.js'; export const validateRequestConnection = [ diff --git a/apps/server/src/api-data/url-presets/urlPresets.router.ts b/apps/server/src/api-data/url-presets/urlPresets.router.ts index 6a61e3e22..6de6fd9a0 100644 --- a/apps/server/src/api-data/url-presets/urlPresets.router.ts +++ b/apps/server/src/api-data/url-presets/urlPresets.router.ts @@ -1,10 +1,11 @@ import express from 'express'; import type { Request, Response } from 'express'; -import { RefetchKey, type ErrorResponse, type URLPreset } from 'ontime-types'; +import { type ErrorResponse, RefetchKey, type URLPreset } from 'ontime-types'; import { getErrorMessage } from 'ontime-utils'; + +import { sendRefetch } from '../../adapters/WebsocketAdapter.js'; import { getDataProvider } from '../../classes/data-provider/DataProvider.js'; import { validateNewPreset, validatePresetParam, validateUpdatePreset } from './urlPresets.validation.js'; -import { sendRefetch } from '../../adapters/WebsocketAdapter.js'; export const router = express.Router(); diff --git a/apps/server/src/api-data/url-presets/urlPresets.validation.ts b/apps/server/src/api-data/url-presets/urlPresets.validation.ts index 7da45e726..48f3e5cc9 100644 --- a/apps/server/src/api-data/url-presets/urlPresets.validation.ts +++ b/apps/server/src/api-data/url-presets/urlPresets.validation.ts @@ -1,6 +1,5 @@ -import { OntimeView } from 'ontime-types'; - import { body, param } from 'express-validator'; +import { OntimeView } from 'ontime-types'; import { requestValidationFunction } from '../validation-utils/validationFunction.js'; diff --git a/apps/server/src/api-data/validation-utils/validationFunction.ts b/apps/server/src/api-data/validation-utils/validationFunction.ts index 7701349f1..55c88a3a9 100644 --- a/apps/server/src/api-data/validation-utils/validationFunction.ts +++ b/apps/server/src/api-data/validation-utils/validationFunction.ts @@ -1,7 +1,8 @@ -import type { Request, Response, NextFunction } from 'express'; +import type { NextFunction, Request, Response } from 'express'; import { param, validationResult } from 'express-validator'; export const paramsWithId = [param('id').isString().trim().notEmpty(), requestValidationFunction]; +type RequestWithFile = Request & { file?: unknown }; // #region operations on project rundowns ========================= @@ -27,8 +28,9 @@ export function requestValidationFunctionWithFile(req: Request, res: Response, n res.status(422).json({ errors: errors.array() }); return; } + const request = req as RequestWithFile; // check that the file exists - if (!req.file) { + if (!request.file) { res.status(422).json({ errors: 'File not found' }); return; } diff --git a/apps/server/src/api-data/view-settings/viewSettings.router.ts b/apps/server/src/api-data/view-settings/viewSettings.router.ts index 8d388a5e8..c15ce646c 100644 --- a/apps/server/src/api-data/view-settings/viewSettings.router.ts +++ b/apps/server/src/api-data/view-settings/viewSettings.router.ts @@ -1,11 +1,11 @@ import express from 'express'; import type { Request, Response } from 'express'; -import { RefetchKey, type ErrorResponse, type ViewSettings } from 'ontime-types'; +import { type ErrorResponse, RefetchKey, type ViewSettings } from 'ontime-types'; import { getErrorMessage } from 'ontime-utils'; -import { validateViewSettings } from './viewSettings.validation.js'; -import { getDataProvider } from '../../classes/data-provider/DataProvider.js'; import { sendRefetch } from '../../adapters/WebsocketAdapter.js'; +import { getDataProvider } from '../../classes/data-provider/DataProvider.js'; +import { validateViewSettings } from './viewSettings.validation.js'; export const router = express.Router(); diff --git a/apps/server/src/api-data/view-settings/viewSettings.validation.ts b/apps/server/src/api-data/view-settings/viewSettings.validation.ts index 84027cd3f..67acde32c 100644 --- a/apps/server/src/api-data/view-settings/viewSettings.validation.ts +++ b/apps/server/src/api-data/view-settings/viewSettings.validation.ts @@ -1,4 +1,5 @@ import { body } from 'express-validator'; + import { requestValidationFunction } from '../validation-utils/validationFunction.js'; /** diff --git a/apps/server/src/api-integration/__test__/integration.utils.test.ts b/apps/server/src/api-integration/__test__/integration.utils.test.ts index ea639877b..f9f1a577d 100644 --- a/apps/server/src/api-integration/__test__/integration.utils.test.ts +++ b/apps/server/src/api-integration/__test__/integration.utils.test.ts @@ -1,140 +1,141 @@ -import { CustomFields, EntryCustomFields, OntimeDelay, OntimeEvent } from 'ontime-types'; -import { isValidChangeProperty } from '../integration.utils.js'; - -describe('isValidChangeProperty()', () => { - test('allows changing a valid event property with valid value', () => { - const testEvent = { - id: 'test', - duration: 111, - } as OntimeEvent; - - expect(isValidChangeProperty(testEvent, 'duration', 123, {})).toBeTruthy(); - }); - - test('forbids changing a valid event property with undefined value', () => { - const testEvent = { - id: 'test', - duration: 111, - } as OntimeEvent; - - expect(isValidChangeProperty(testEvent, 'duration', undefined, {})).toBeFalsy(); - }); - - test('forbids changing a non-existing property', () => { - const testEvent = { - id: 'test', - duration: 111, - } as OntimeEvent; - - expect(isValidChangeProperty(testEvent, 'missing', 123, {})).toBeFalsy(); - }); - - test('forbids changing customValues in event without custom fields', () => { - const testDelay = { - id: 'test', - duration: 111, - } as OntimeDelay; - - const testCustomFields = { - test: { - type: 'text', - colour: '#ffffff', - label: 'Test Field', - }, - } satisfies CustomFields; - - expect(isValidChangeProperty(testDelay, 'custom:test', 123, testCustomFields)).toBeFalsy(); - }); - - test('forbids changing a non-existing custom value', () => { - const testEvent = { - id: 'test', - duration: 111, - custom: { - field: 'test', - } as EntryCustomFields, - } as OntimeEvent; - - expect(isValidChangeProperty(testEvent, 'custom:test', 123, {})).toBeFalsy(); - }); - - test('allows changing an existing custom value', () => { - const testEvent = { - id: 'test', - duration: 111, - custom: { - test: 'test', - } as EntryCustomFields, - } as OntimeEvent; - - const testCustomFields = { - test: { - type: 'text', - colour: '#ffffff', - label: 'Test Field', - }, - } satisfies CustomFields; - - expect(isValidChangeProperty(testEvent, 'custom:test', 123, testCustomFields)).toBeTruthy(); - }); - - test('forbids changing a custom field with a missing value', () => { - const testEvent = { - id: 'test', - duration: 111, - custom: { - test: 'test', - } as EntryCustomFields, - } as OntimeEvent; - - const testCustomFields = { - test: { - type: 'text', - colour: '#ffffff', - label: 'Test Field', - }, - } satisfies CustomFields; - - expect(isValidChangeProperty(testEvent, 'custom:', 123, testCustomFields)).toBeFalsy(); - }); - - test('forbids references to prototype properties in custom object', () => { - const testEvent = { - id: 'test', - duration: 111, - custom: { - test: 'test', - } as EntryCustomFields, - } as OntimeEvent; - - const testCustomFields = { - test: { - type: 'text', - colour: '#ffffff', - label: 'Test Field', - }, - } satisfies CustomFields; - - expect(isValidChangeProperty(testEvent, 'custom:toString', 123, testCustomFields)).toBeFalsy(); - }); - - test('forbids references to prototype properties in object', () => { - const testEvent = { - id: 'test', - duration: 111, - custom: { - test: 'test', - } as EntryCustomFields, - } as OntimeEvent; - - const testCustomFields = { - test: { - type: 'text', - colour: '#ffffff', - label: 'Test Field', - }, - } satisfies CustomFields; - - expect(isValidChangeProperty(testEvent, 'toString', 123, testCustomFields)).toBeFalsy(); - }); -}); +import { CustomFields, EntryCustomFields, OntimeDelay, OntimeEvent } from 'ontime-types'; + +import { isValidChangeProperty } from '../integration.utils.js'; + +describe('isValidChangeProperty()', () => { + test('allows changing a valid event property with valid value', () => { + const testEvent = { + id: 'test', + duration: 111, + } as OntimeEvent; + + expect(isValidChangeProperty(testEvent, 'duration', 123, {})).toBeTruthy(); + }); + + test('forbids changing a valid event property with undefined value', () => { + const testEvent = { + id: 'test', + duration: 111, + } as OntimeEvent; + + expect(isValidChangeProperty(testEvent, 'duration', undefined, {})).toBeFalsy(); + }); + + test('forbids changing a non-existing property', () => { + const testEvent = { + id: 'test', + duration: 111, + } as OntimeEvent; + + expect(isValidChangeProperty(testEvent, 'missing', 123, {})).toBeFalsy(); + }); + + test('forbids changing customValues in event without custom fields', () => { + const testDelay = { + id: 'test', + duration: 111, + } as OntimeDelay; + + const testCustomFields = { + test: { + type: 'text', + colour: '#ffffff', + label: 'Test Field', + }, + } satisfies CustomFields; + + expect(isValidChangeProperty(testDelay, 'custom:test', 123, testCustomFields)).toBeFalsy(); + }); + + test('forbids changing a non-existing custom value', () => { + const testEvent = { + id: 'test', + duration: 111, + custom: { + field: 'test', + } as EntryCustomFields, + } as OntimeEvent; + + expect(isValidChangeProperty(testEvent, 'custom:test', 123, {})).toBeFalsy(); + }); + + test('allows changing an existing custom value', () => { + const testEvent = { + id: 'test', + duration: 111, + custom: { + test: 'test', + } as EntryCustomFields, + } as OntimeEvent; + + const testCustomFields = { + test: { + type: 'text', + colour: '#ffffff', + label: 'Test Field', + }, + } satisfies CustomFields; + + expect(isValidChangeProperty(testEvent, 'custom:test', 123, testCustomFields)).toBeTruthy(); + }); + + test('forbids changing a custom field with a missing value', () => { + const testEvent = { + id: 'test', + duration: 111, + custom: { + test: 'test', + } as EntryCustomFields, + } as OntimeEvent; + + const testCustomFields = { + test: { + type: 'text', + colour: '#ffffff', + label: 'Test Field', + }, + } satisfies CustomFields; + + expect(isValidChangeProperty(testEvent, 'custom:', 123, testCustomFields)).toBeFalsy(); + }); + + test('forbids references to prototype properties in custom object', () => { + const testEvent = { + id: 'test', + duration: 111, + custom: { + test: 'test', + } as EntryCustomFields, + } as OntimeEvent; + + const testCustomFields = { + test: { + type: 'text', + colour: '#ffffff', + label: 'Test Field', + }, + } satisfies CustomFields; + + expect(isValidChangeProperty(testEvent, 'custom:toString', 123, testCustomFields)).toBeFalsy(); + }); + + test('forbids references to prototype properties in object', () => { + const testEvent = { + id: 'test', + duration: 111, + custom: { + test: 'test', + } as EntryCustomFields, + } as OntimeEvent; + + const testCustomFields = { + test: { + type: 'text', + colour: '#ffffff', + label: 'Test Field', + }, + } satisfies CustomFields; + + expect(isValidChangeProperty(testEvent, 'toString', 123, testCustomFields)).toBeFalsy(); + }); +}); diff --git a/apps/server/src/api-integration/integration.controller.ts b/apps/server/src/api-integration/integration.controller.ts index 9d9f47393..bd496e8af 100644 --- a/apps/server/src/api-integration/integration.controller.ts +++ b/apps/server/src/api-integration/integration.controller.ts @@ -8,9 +8,12 @@ import { SimplePlayback, } from 'ontime-types'; import { MILLIS_PER_HOUR } from 'ontime-utils'; - import { DeepPartial } from 'ts-essentials'; +import { socket } from '../adapters/WebsocketAdapter.js'; +import { getCurrentRundown, getProjectCustomFields } from '../api-data/rundown/rundown.dao.js'; +import { editEntry } from '../api-data/rundown/rundown.service.js'; +import { willCauseRegeneration } from '../api-data/rundown/rundown.utils.js'; import { ONTIME_VERSION } from '../ONTIME_VERSION.js'; import { auxTimerService } from '../services/aux-timer-service/AuxTimerService.js'; import * as messageService from '../services/message-service/message.service.js'; @@ -18,12 +21,8 @@ import { validateMessage, validateTimerMessage } from '../services/message-servi import { runtimeService } from '../services/runtime-service/runtime.service.js'; import { eventStore } from '../stores/EventStore.js'; import * as assert from '../utils/assert.js'; -import { parseProperty, isValidChangeProperty } from './integration.utils.js'; -import { socket } from '../adapters/WebsocketAdapter.js'; import { coerceEnum } from '../utils/coerceType.js'; -import { editEntry } from '../api-data/rundown/rundown.service.js'; -import { willCauseRegeneration } from '../api-data/rundown/rundown.utils.js'; -import { getCurrentRundown, getProjectCustomFields } from '../api-data/rundown/rundown.dao.js'; +import { isValidChangeProperty, parseProperty } from './integration.utils.js'; let lastRequest: Date | null = null; diff --git a/apps/server/src/api-integration/integration.router.ts b/apps/server/src/api-integration/integration.router.ts index 49c51bf16..22857427e 100644 --- a/apps/server/src/api-integration/integration.router.ts +++ b/apps/server/src/api-integration/integration.router.ts @@ -5,16 +5,14 @@ * */ -import { ErrorResponse, LogOrigin } from 'ontime-types'; - import express, { type Request, type Response } from 'express'; - -import { logger } from '../classes/Logger.js'; -import { integrationPayloadFromPath } from '../adapters/utils/parse.js'; - -import { dispatchFromAdapter } from './integration.controller.js'; +import { ErrorResponse, LogOrigin } from 'ontime-types'; import { getErrorMessage } from 'ontime-utils'; + +import { integrationPayloadFromPath } from '../adapters/utils/parse.js'; +import { logger } from '../classes/Logger.js'; import { isEmptyObject } from '../utils/parserUtils.js'; +import { dispatchFromAdapter } from './integration.controller.js'; export const integrationRouter = express.Router(); diff --git a/apps/server/src/app.ts b/apps/server/src/app.ts index 2a7a9aaeb..4ff999c70 100644 --- a/apps/server/src/app.ts +++ b/apps/server/src/app.ts @@ -1,53 +1,47 @@ -import { LogOrigin, runtimeStorePlaceholder, SimpleDirection, SimplePlayback } from 'ontime-types'; +import http, { type Server } from 'http'; import 'dotenv/config'; -import express from 'express'; -import http, { type Server } from 'http'; -import cors from 'cors'; -import serverTiming from 'server-timing'; import cookieParser from 'cookie-parser'; +import cors from 'cors'; +import express from 'express'; +import { LogOrigin, SimpleDirection, SimplePlayback, runtimeStorePlaceholder } from 'ontime-types'; +import serverTiming from 'server-timing'; -// import utils -import { publicDir, srcDir } from './setup/index.js'; -import { environment, isProduction } from './setup/environment.js'; -import { updateRouterPrefix } from './externals.js'; -import { ONTIME_VERSION } from './ONTIME_VERSION.js'; -import { consoleSuccess, consoleHighlight, consoleError } from './utils/console.js'; - -// Import middleware configuration -import { bodyParser } from './middleware/bodyParser.js'; -import { compressedStatic } from './middleware/staticGZip.js'; -import { makeLoginRouter, makeAuthenticateMiddleware } from './middleware/authenticate.js'; - +import { oscServer } from './adapters/OscAdapter.js'; +// Import adapters +import { socket } from './adapters/WebsocketAdapter.js'; // Import Routers import { appRouter } from './api-data/index.js'; import { integrationRouter } from './api-integration/integration.router.js'; - -// Import adapters -import { socket } from './adapters/WebsocketAdapter.js'; -import { getDataProvider, flushPendingWrites } from './classes/data-provider/DataProvider.js'; - +import { flushPendingWrites, getDataProvider } from './classes/data-provider/DataProvider.js'; // Services import { logger } from './classes/Logger.js'; -import { populateDemo } from './setup/loadDemo.js'; -import { populateTranslation } from './setup/loadTranslations.js'; -import { populateStyles } from './setup/loadStyles.js'; -import { eventStore } from './stores/EventStore.js'; -import { runtimeService } from './services/runtime-service/runtime.service.js'; +import { portManager } from './classes/port-manager/PortManager.js'; +import { updateRouterPrefix } from './externals.js'; +import { makeAuthenticateMiddleware, makeLoginRouter } from './middleware/authenticate.js'; +// Import middleware configuration +import { bodyParser } from './middleware/bodyParser.js'; +import { compressedStatic } from './middleware/staticGZip.js'; +import { ONTIME_VERSION } from './ONTIME_VERSION.js'; +import { getShowWelcomeDialog } from './services/app-state-service/AppStateService.js'; +import * as messageService from './services/message-service/message.service.js'; +import { initialiseProject } from './services/project-service/ProjectService.js'; import { restoreService } from './services/restore-service/restore.service.js'; import type { RestorePoint } from './services/restore-service/restore.type.js'; -import * as messageService from './services/message-service/message.service.js'; -import { getState } from './stores/runtimeState.js'; -import { initialiseProject } from './services/project-service/ProjectService.js'; -import { getShowWelcomeDialog } from './services/app-state-service/AppStateService.js'; -import { oscServer } from './adapters/OscAdapter.js'; - -// Utilities -import { clearUploadfolder } from './utils/upload.js'; -import { generateCrashReport } from './utils/generateCrashReport.js'; +import { runtimeService } from './services/runtime-service/runtime.service.js'; import { timerConfig } from './setup/config.js'; +import { environment, isProduction } from './setup/environment.js'; +// import utils +import { publicDir, srcDir } from './setup/index.js'; +import { populateDemo } from './setup/loadDemo.js'; +import { populateStyles } from './setup/loadStyles.js'; +import { populateTranslation } from './setup/loadTranslations.js'; +import { eventStore } from './stores/EventStore.js'; +import { getState } from './stores/runtimeState.js'; +import { consoleError, consoleHighlight, consoleSuccess } from './utils/console.js'; +import { generateCrashReport } from './utils/generateCrashReport.js'; import { getNetworkInterfaces } from './utils/network.js'; -import { portManager } from './classes/port-manager/PortManager.js'; +import { clearUploadfolder } from './utils/upload.js'; console.log('\n'); consoleHighlight(`Starting Ontime version ${ONTIME_VERSION}`); diff --git a/apps/server/src/classes/Logger.ts b/apps/server/src/classes/Logger.ts index 3bb79f2ec..b002cf89e 100644 --- a/apps/server/src/classes/Logger.ts +++ b/apps/server/src/classes/Logger.ts @@ -2,9 +2,9 @@ import { Log, LogLevel, MessageTag } from 'ontime-types'; import { generateId, millisToString } from 'ontime-utils'; import { socket } from '../adapters/WebsocketAdapter.js'; -import { consoleSubdued, consoleError } from '../utils/console.js'; -import { timeNow } from '../utils/time.js'; import { isProduction } from '../setup/environment.js'; +import { consoleError, consoleSubdued } from '../utils/console.js'; +import { timeNow } from '../utils/time.js'; class Logger { private queue: Log[]; diff --git a/apps/server/src/classes/data-provider/DataProvider.ts b/apps/server/src/classes/data-provider/DataProvider.ts index 4df2d6b79..50e10e422 100644 --- a/apps/server/src/classes/data-provider/DataProvider.ts +++ b/apps/server/src/classes/data-provider/DataProvider.ts @@ -1,22 +1,20 @@ -import { - ProjectData, - ViewSettings, - DatabaseModel, - Settings, - CustomFields, - URLPreset, - AutomationSettings, - Rundown, - ProjectRundowns, -} from 'ontime-types'; - import type { Low } from 'lowdb'; import { JSONFilePreset } from 'lowdb/node'; +import { + AutomationSettings, + CustomFields, + DatabaseModel, + ProjectData, + ProjectRundowns, + Rundown, + Settings, + URLPreset, + ViewSettings, +} from 'ontime-types'; -import { isPath } from '../../utils/fileManagement.js'; -import { shouldCrashDev } from '../../utils/development.js'; import { isTest } from '../../setup/environment.js'; - +import { shouldCrashDev } from '../../utils/development.js'; +import { isPath } from '../../utils/fileManagement.js'; import { safeMerge } from './DataProvider.utils.js'; type ReadonlyPromise = Promise>; diff --git a/apps/server/src/classes/data-provider/__tests__/DataProvider.utils.test.ts b/apps/server/src/classes/data-provider/__tests__/DataProvider.utils.test.ts index 7a9aa5988..752810dcb 100644 --- a/apps/server/src/classes/data-provider/__tests__/DataProvider.utils.test.ts +++ b/apps/server/src/classes/data-provider/__tests__/DataProvider.utils.test.ts @@ -1,8 +1,7 @@ import { AutomationSettings, CustomField, DatabaseModel, Settings, TimerLifeCycle, URLPreset } from 'ontime-types'; -import { makeNewProject } from '../../../models/dataModel.js'; import { makeOntimeEvent, makeRundown } from '../../../api-data/rundown/__mocks__/rundown.mocks.js'; - +import { makeNewProject } from '../../../models/dataModel.js'; import { safeMerge } from '../DataProvider.utils.js'; const baseDb = makeNewProject('demo'); diff --git a/apps/server/src/classes/port-manager/PortManager.ts b/apps/server/src/classes/port-manager/PortManager.ts index 891e60acf..455734353 100644 --- a/apps/server/src/classes/port-manager/PortManager.ts +++ b/apps/server/src/classes/port-manager/PortManager.ts @@ -1,11 +1,13 @@ -import { Server } from "http"; -import { config } from "../../setup/config.js"; -import { envPort, isDocker, isOntimeCloud } from "../../setup/environment.js"; -import * as appState from "../../services/app-state-service/AppStateService.js"; -import { logger } from "../Logger.js"; -import { LogOrigin, MaybeNumber } from "ontime-types"; -import { isAddressInfo, isPortInUseError } from "./PortManager.utils.js"; -import { shouldCrashDev } from "../../utils/development.js"; +import { Server } from 'http'; + +import { LogOrigin, MaybeNumber } from 'ontime-types'; + +import * as appState from '../../services/app-state-service/AppStateService.js'; +import { config } from '../../setup/config.js'; +import { envPort, isDocker, isOntimeCloud } from '../../setup/environment.js'; +import { shouldCrashDev } from '../../utils/development.js'; +import { logger } from '../Logger.js'; +import { isAddressInfo, isPortInUseError } from './PortManager.utils.js'; class PortManager { private static port: number; @@ -27,7 +29,7 @@ class PortManager { * @returns {void} */ public changePort(newPort: number): void { - if (isDocker) throw new Error("Can not change port when running inside docker"); + if (isDocker) throw new Error('Can not change port when running inside docker'); if (PortManager.port === newPort) return; PortManager.newPort = newPort; PortManager.pendingRestart = true; @@ -36,7 +38,7 @@ class PortManager { public migratePortFromProjectFile(port: number) { shouldCrashDev( PortManager.port !== undefined, - "this function should not be called after `PortManager.port` has been initialized", + 'this function should not be called after `PortManager.port` has been initialized', ); appState.setServerPort(port); } @@ -61,8 +63,7 @@ class PortManager { if (isOntimeCloud) { PortManager.port = await this.forceCloudPort(server); } else { - PortManager.port = - this.parsePort(envPort) || (await appState.getServerPort()) || config.defaultServerPort; + PortManager.port = this.parsePort(envPort) || (await appState.getServerPort()) || config.defaultServerPort; PortManager.port = await this.tryServerPort(server); } await appState.setServerPort(PortManager.port); @@ -70,8 +71,8 @@ class PortManager { } private parsePort(port: string | undefined) { - if (typeof port !== "string") return null; - if (port === "") return null; + if (typeof port !== 'string') return null; + if (port === '') return null; const maybePort = Number(port); if (isNaN(maybePort)) return null; return maybePort; @@ -79,7 +80,7 @@ class PortManager { private async tryServerPort(server: Server): Promise { return new Promise((resolve, reject) => { - server.once("error", (error) => { + server.once('error', (error) => { // we should only move ports if we are in a desktop environment if (isDocker) { reject(error); @@ -93,10 +94,10 @@ class PortManager { // if we get an address in use error, we will try to open the server in an ephemeral port // port 0 will assign an ephemeral port - server.listen(0, "0.0.0.0", () => { + server.listen(0, '0.0.0.0', () => { const address = server.address(); if (!isAddressInfo(address)) { - reject(new Error("Unknown port type, unable to proceed")); + reject(new Error('Unknown port type, unable to proceed')); return; } logger.error( @@ -109,10 +110,10 @@ class PortManager { }); }); - server.listen(PortManager.port, "0.0.0.0", () => { + server.listen(PortManager.port, '0.0.0.0', () => { const address = server.address(); if (!isAddressInfo(address)) { - reject(new Error("Unknown port type, unable to proceed")); + reject(new Error('Unknown port type, unable to proceed')); return; } resolve(address.port); @@ -122,13 +123,13 @@ class PortManager { private forceCloudPort(server: Server): Promise { return new Promise((resolve, reject) => { - server.once("error", (error) => { + server.once('error', (error) => { reject(error); }); - server.listen(config.defaultServerPort, "0.0.0.0", () => { + server.listen(config.defaultServerPort, '0.0.0.0', () => { const address = server.address(); if (!isAddressInfo(address)) { - reject(new Error("Unknown port type, unable to proceed")); + reject(new Error('Unknown port type, unable to proceed')); return; } resolve(address.port); diff --git a/apps/server/src/external/README.md b/apps/server/src/external/README.md index f38532fdb..401b25594 100644 --- a/apps/server/src/external/README.md +++ b/apps/server/src/external/README.md @@ -2,7 +2,8 @@ This folder contains resources which will be distributed as part of Ontime's infrastructure. Folders added here would be available at -``` bash + +```bash http://:/external/ ``` diff --git a/apps/server/src/external/demo/index.html b/apps/server/src/external/demo/index.html index f4a68812f..298320d3c 100644 --- a/apps/server/src/external/demo/index.html +++ b/apps/server/src/external/demo/index.html @@ -1,114 +1,116 @@ - + - - - - - - ontime demo - - + + + + + ontime demo + + - -
-
- Ontime logo -

Ontime demo

-
-
- Last message received at - - -
- -
+ +
+
+ Ontime logo +

Ontime demo

+
+
+ Last message received at + - +
+ +
-
-
-
- Timer -
-
Current timer values
- - -
-
-
- Rundown -
-
Progress of the current rundown
- - -
-
-
- Offset -
-
Runtime offset and timings for upcoming targets
- - -
-
-
-
-
- Event now -
-
Currently loaded event
- - -
-
-
- Event next -
-
Next scheduled event
- - -
-
-
-
-
- Group now -
-
Currently active group
- - -
-
-
- Event flag -
-
Currently targeted flag
- - -
-
-
-
-
- Message -
-
Messaging feature
- - -
-
-
- Aux timers -
-
Auxiliary Timer 1
- - -
-
-
Auxiliary Timer 2
- - -
-
-
Auxiliary Timer 3
- - -
-
-
-
- - +
+
+
+ Timer +
+
Current timer values
+ - +
+
+
+ Rundown +
+
Progress of the current rundown
+ - +
+
+
+ Offset +
+
Runtime offset and timings for upcoming targets
+ - +
+
+
+
+
+ Event now +
+
Currently loaded event
+ - +
+
+
+ Event next +
+
Next scheduled event
+ - +
+
+
+
+
+ Group now +
+
Currently active group
+ - +
+
+
+ Event flag +
+
Currently targeted flag
+ - +
+
+
+
+
+ Message +
+
Messaging feature
+ - +
+
+
+ Aux timers +
+
Auxiliary Timer 1
+ - +
+
+
Auxiliary Timer 2
+ - +
+
+
Auxiliary Timer 3
+ - +
+
+
+
- \ No newline at end of file + + + diff --git a/apps/server/src/externals.ts b/apps/server/src/externals.ts index 24c40ec1d..5229ecca6 100644 --- a/apps/server/src/externals.ts +++ b/apps/server/src/externals.ts @@ -4,8 +4,8 @@ import { readFileSync, writeFileSync } from 'node:fs'; -import { srcFiles } from './setup/index.js'; import { isOntimeCloud } from './setup/environment.js'; +import { srcFiles } from './setup/index.js'; // ================================================= export const password = process.env.SESSION_PASSWORD; diff --git a/apps/server/src/html/login.html b/apps/server/src/html/login.html index 3f8d3921a..40db5a049 100644 --- a/apps/server/src/html/login.html +++ b/apps/server/src/html/login.html @@ -10,8 +10,8 @@