Compare commits

...

11 Commits

Author SHA1 Message Date
Carlos Valente a9ee0c3f1d feat/120: prevent reflow (#166) 2022-06-30 23:34:23 +02:00
Carlos Valente f4c5a2bf87 Feat/120 (#164)
* feat/120: calculate delay to single event
* feat/120 Countdown
* feat/120 prevent parsing NaN
* feat/120: version bump
* feat/120: update README.md
* feat/120: show delayed countdown timer
2022-06-30 20:26:01 +02:00
Carlos Valente dcc534f92b add timeout to test CI 2022-06-16 22:44:46 +02:00
Carlos Valente 2ee4986dcf Update build.yml
add timeout to build steps
2022-06-16 22:43:54 +02:00
Carlos Valente c1de3190e9 Fix/155 (#158)
* fix/155: fix css polution on detached views
* fix/155: test detached routes
2022-06-16 14:27:13 +02:00
Carlos Valente 1f001cf188 Feat/153 (#157)
* feat/153: always roll
* feat/153: version bump
2022-06-15 20:37:21 +02:00
Carlos Valente 323d365f1a Fix/147 (#152)
* fix/147: add latest tag to release
* fix/147: add latest tag to docker compose
* fix/148: add timezone example to docker-compose
* docker: version bump
2022-06-13 22:11:17 +02:00
Carlos Valente dda92ba3a8 Refactor imports
* refactor: implement import lint
2022-06-11 23:17:16 +02:00
Carlos Valente c576b6308e Update build.yml 2022-06-08 22:22:03 +02:00
Carlos Valente 5802e7cd03 Update build.yml 2022-06-08 22:14:38 +02:00
Carlos Valente 86957593bb Update build.yml 2022-06-08 22:03:28 +02:00
130 changed files with 1246 additions and 495 deletions
+9 -3
View File
@@ -10,6 +10,7 @@ on:
jobs: jobs:
build_mac: build_mac:
runs-on: macOS-latest runs-on: macOS-latest
timeout-minutes: 20
env: env:
CI: '' CI: ''
@@ -53,6 +54,7 @@ jobs:
build_win: build_win:
runs-on: windows-latest runs-on: windows-latest
timeout-minutes: 20
env: env:
CI: '' CI: ''
@@ -96,6 +98,7 @@ jobs:
build_linux: build_linux:
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 20
env: env:
CI: '' CI: ''
@@ -139,6 +142,7 @@ jobs:
publish_docker: publish_docker:
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 20
env: env:
CI: '' CI: ''
@@ -172,13 +176,15 @@ jobs:
username: ${{ secrets.DOCKERHUB_USERNAME }} username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }} password: ${{ secrets.DOCKERHUB_TOKEN }}
# Prepare builder
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
# Build and push # Build and push
- name: Build and push - name: Build and push
working-directory: ./
id: docker_build
uses: docker/build-push-action@v2 uses: docker/build-push-action@v2
with: with:
context: . context: .
file: ./Dockerfile file: ./Dockerfile
push: true push: true
tags: ${{ secrets.DOCKERHUB_USERNAME }}/ontime:${{ env.RELEASE_VERSION }} tags: ${{ secrets.DOCKERHUB_USERNAME }}/ontime:${{ env.RELEASE_VERSION }} ${{ secrets.DOCKERHUB_USERNAME }}/ontime:latest
+1
View File
@@ -9,6 +9,7 @@ jobs:
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 20
env: env:
CI: '' CI: ''
+1
View File
@@ -80,6 +80,7 @@ More documentation available [here](https://cpvalente.gitbook.io/ontime/)
same as app) same as app)
- [x] Multi platform (available on Windows, MacOS and Linux) - [x] Multi platform (available on Windows, MacOS and Linux)
- [x] [Headless run](#headless-run) (run server only, configure from a browser locally) - [x] [Headless run](#headless-run) (run server only, configure from a browser locally)
- [x] [Countdown to anything!](https://cpvalente.gitbook.io/ontime/views/countdown): ability to have a countdown to any scheduled event
## Unopinionated ## Unopinionated
+55 -3
View File
@@ -7,7 +7,8 @@
"plugins": [ "plugins": [
"react", "react",
"testing-library", "testing-library",
"jest" "jest",
"simple-import-sort"
], ],
"rules": { "rules": {
"jest/no-mocks-import": "warn", "jest/no-mocks-import": "warn",
@@ -77,6 +78,57 @@
"customValidators": [], "customValidators": [],
"skipUndeclared": true "skipUndeclared": true
} }
] ],
} "simple-import-sort/imports": "warn",
"simple-import-sort/exports": "warn",
"import/no-duplicates": "error"
},
"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)$"
]
]
}
]
}
}
]
} }
+3 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "ontime-ui", "name": "ontime-ui",
"version": "1.1.1", "version": "1.2.1",
"private": true, "private": true,
"dependencies": { "dependencies": {
"@chakra-ui/react": "^2.0.0-next.3", "@chakra-ui/react": "^2.0.0-next.3",
@@ -30,6 +30,7 @@
"scripts": { "scripts": {
"start": "set BROWSER=none&&react-scripts start", "start": "set BROWSER=none&&react-scripts start",
"build": "react-scripts build", "build": "react-scripts build",
"lint": "eslint .",
"test": "react-scripts test", "test": "react-scripts test",
"test:pipeline": "react-scripts test --watchAll=false --runInBand --detectOpenHandles --forceExit ", "test:pipeline": "react-scripts test --watchAll=false --runInBand --detectOpenHandles --forceExit ",
"eject": "react-scripts eject" "eject": "react-scripts eject"
@@ -51,6 +52,7 @@
"@testing-library/react": "^13.1.1", "@testing-library/react": "^13.1.1",
"@testing-library/react-hooks": "^8.0.0", "@testing-library/react-hooks": "^8.0.0",
"@testing-library/user-event": "^14.1.1", "@testing-library/user-event": "^14.1.1",
"eslint-plugin-simple-import-sort": "^7.0.0",
"prop-types": "^15.8.1", "prop-types": "^15.8.1",
"react-scripts": "^5.0.1", "react-scripts": "^5.0.1",
"react-test-renderer": "^18.1.0", "react-test-renderer": "^18.1.0",
+9 -3
View File
@@ -1,17 +1,20 @@
import React, { lazy, Suspense, useCallback, useEffect } from 'react'; import React, { lazy, Suspense, useCallback, useEffect } from 'react';
import { Route, Routes, useLocation, useNavigate } from 'react-router-dom'; import { Route, Routes, useLocation, useNavigate } from 'react-router-dom';
import './App.scss';
import withSocket from 'features/viewers/ViewWrapper';
import ErrorBoundary from 'common/components/errorBoundary/ErrorBoundary'; import ErrorBoundary from 'common/components/errorBoundary/ErrorBoundary';
import { useFetch } from './app/hooks/useFetch'; import withSocket from 'features/viewers/ViewWrapper';
import { ALIASES } from './app/api/apiConstants'; import { ALIASES } from './app/api/apiConstants';
import { getAliases } from './app/api/ontimeApi'; import { getAliases } from './app/api/ontimeApi';
import { useFetch } from './app/hooks/useFetch';
import './App.scss';
const Editor = lazy(() => import('features/editors/ProtectedEditor')); const Editor = lazy(() => import('features/editors/ProtectedEditor'));
const Table = lazy(() => import('features/table/ProtectedTable')); const Table = lazy(() => import('features/table/ProtectedTable'));
const TimerView = lazy(() => import('features/viewers/timer/Timer')); const TimerView = lazy(() => import('features/viewers/timer/Timer'));
const MinimalTimerView = lazy(() => import('features/viewers/timer/MinimalTimer')); const MinimalTimerView = lazy(() => import('features/viewers/timer/MinimalTimer'));
const Countdown = lazy(() => import('features/viewers/countdown/Countdown'));
const StageManager = lazy(() => import('features/viewers/backstage/StageManager')); const StageManager = lazy(() => import('features/viewers/backstage/StageManager'));
const Public = lazy(() => import('features/viewers/foh/Public')); const Public = lazy(() => import('features/viewers/foh/Public'));
@@ -21,6 +24,7 @@ const StudioClock = lazy(() => import('features/viewers/studio/StudioClock'));
const STimer = withSocket(TimerView); const STimer = withSocket(TimerView);
const SMinimalTimer = withSocket(MinimalTimerView); const SMinimalTimer = withSocket(MinimalTimerView);
const SCountdown = withSocket(Countdown);
const SStageManager = withSocket(StageManager); const SStageManager = withSocket(StageManager);
const SPublic = withSocket(Public); const SPublic = withSocket(Public);
const SLowerThird = withSocket(Lower); const SLowerThird = withSocket(Lower);
@@ -90,6 +94,8 @@ function App() {
<Route path='/minimalTimer' element={<SMinimalTimer />} /> <Route path='/minimalTimer' element={<SMinimalTimer />} />
<Route path='/simpleTimer' element={<SMinimalTimer />} /> <Route path='/simpleTimer' element={<SMinimalTimer />} />
<Route path='/countdown' element={<SCountdown />} />
<Route path='/sm' element={<SStageManager />} /> <Route path='/sm' element={<SStageManager />} />
<Route path='/backstage' element={<SStageManager />} /> <Route path='/backstage' element={<SStageManager />} />
+1
View File
@@ -1,4 +1,5 @@
import axios from 'axios'; import axios from 'axios';
import { eventURL } from './apiConstants'; import { eventURL } from './apiConstants';
/** /**
+1
View File
@@ -1,4 +1,5 @@
import axios from 'axios'; import axios from 'axios';
import { eventsURL } from './apiConstants'; import { eventsURL } from './apiConstants';
/** /**
+1
View File
@@ -1,4 +1,5 @@
import axios from 'axios'; import axios from 'axios';
import { ontimeURL } from './apiConstants'; import { ontimeURL } from './apiConstants';
/** /**
+1
View File
@@ -1,4 +1,5 @@
import axios from 'axios'; import axios from 'axios';
import { playbackURL } from './apiConstants'; import { playbackURL } from './apiConstants';
/** /**
+2 -1
View File
@@ -1,7 +1,8 @@
import React, { createContext, useCallback, useEffect, useState } from 'react'; import React, { createContext, useCallback, useEffect, useState } from 'react';
import { useFetch } from '../hooks/useFetch';
import { APP_SETTINGS } from '../api/apiConstants'; import { APP_SETTINGS } from '../api/apiConstants';
import { getSettings } from '../api/ontimeApi'; import { getSettings } from '../api/ontimeApi';
import { useFetch } from '../hooks/useFetch';
export const AppContext = createContext({ export const AppContext = createContext({
auth: false, auth: false,
@@ -1,4 +1,5 @@
import React, { createContext, useCallback } from 'react'; import React, { createContext, useCallback } from 'react';
import { useLocalStorage } from '../hooks/useLocalStorage'; import { useLocalStorage } from '../hooks/useLocalStorage';
export const CollapseContext = createContext({ export const CollapseContext = createContext({
+1
View File
@@ -1,4 +1,5 @@
import React, { createContext, useCallback, useMemo, useState } from 'react'; import React, { createContext, useCallback, useMemo, useState } from 'react';
import { useLocalStorage } from '../hooks/useLocalStorage'; import { useLocalStorage } from '../hooks/useLocalStorage';
export const CursorContext = createContext({ export const CursorContext = createContext({
+3 -1
View File
@@ -1,8 +1,10 @@
import React, { createContext, useCallback, useEffect, useState } from 'react'; import React, { createContext, useCallback, useEffect, useState } from 'react';
import { useSocket } from './socketContext';
import { generateId } from '../../common/utils/generate_id'; import { generateId } from '../../common/utils/generate_id';
import { nowInMillis, stringFromMillis } from '../../common/utils/time'; import { nowInMillis, stringFromMillis } from '../../common/utils/time';
import { useSocket } from './socketContext';
export const LoggingContext = createContext({ export const LoggingContext = createContext({
logData: [], logData: [],
emitInfo: () => undefined, emitInfo: () => undefined,
@@ -1,4 +1,5 @@
import React, { createContext, useCallback, useState } from 'react'; import React, { createContext, useCallback, useState } from 'react';
import { useLocalStorage } from '../hooks/useLocalStorage'; import { useLocalStorage } from '../hooks/useLocalStorage';
export const TableSettingsContext = createContext({ export const TableSettingsContext = createContext({
+1 -1
View File
@@ -1,6 +1,6 @@
import React, { createContext, useContext, useEffect, useState } from 'react'; import React, { createContext, useContext, useEffect, useState } from 'react';
import io from 'socket.io-client';
import { serverURL } from 'app/api/apiConstants'; import { serverURL } from 'app/api/apiConstants';
import io from 'socket.io-client';
const SocketContext = createContext([[], () => {}]); const SocketContext = createContext([[], () => {}]);
+1
View File
@@ -1,4 +1,5 @@
import { useMutation, useQueryClient } from 'react-query'; import { useMutation, useQueryClient } from 'react-query';
import { EVENTS_TABLE } from '../api/apiConstants'; import { EVENTS_TABLE } from '../api/apiConstants';
/** /**
-52
View File
@@ -1,52 +0,0 @@
const dummy = new Date();
export const sampleData = {
presenterMessage: {
text: 'Only the timer sees this',
active: false,
},
publicMessage: {
text: 'Everyone sees this',
active: false,
},
events: [
{
id: '1',
title: 'Is the internet a fad?',
subtitle: 'It is',
presenter: 'Carlos Valente',
timeStart: 37800000,
timeEnd: 39600000,
clockStarted: dummy,
timerDuration: 60,
type: 'event',
},
{
id: 0.4849093424577693,
duration: 25*60000,
type: 'delay',
},
{
id: '2',
title: 'Is reddit a dictatorship?',
subtitle: 'It is',
presenter: 'Carlos Valente',
timeStart: 39600000,
timeEnd: 40320000,
clockStarted: dummy,
timerDuration: 60*60000,
type: 'event',
},
{
id: '3',
title: 'Out of words',
subtitle: '',
presenter: 'Carlos Valente',
timeStart: 41400000,
timeEnd: 43200000,
clockStarted: dummy,
timerDuration: 60,
type: 'event',
},
],
};
@@ -1,10 +1,10 @@
import React from 'react'; import React from 'react';
import { Menu, MenuButton, MenuItem, MenuList } from '@chakra-ui/menu';
import { IconButton } from '@chakra-ui/button'; import { IconButton } from '@chakra-ui/button';
import { Menu, MenuButton, MenuItem, MenuList } from '@chakra-ui/menu';
import { Tooltip } from '@chakra-ui/tooltip';
import { FiClock } from '@react-icons/all-files/fi/FiClock'; import { FiClock } from '@react-icons/all-files/fi/FiClock';
import { FiMinusCircle } from '@react-icons/all-files/fi/FiMinusCircle'; import { FiMinusCircle } from '@react-icons/all-files/fi/FiMinusCircle';
import { FiPlus } from '@react-icons/all-files/fi/FiPlus'; import { FiPlus } from '@react-icons/all-files/fi/FiPlus';
import { Tooltip } from '@chakra-ui/tooltip';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
export default function ActionButtons(props) { export default function ActionButtons(props) {
@@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import { IoCloseSharp } from '@react-icons/all-files/io5/IoCloseSharp';
import { IoCheckmarkSharp } from '@react-icons/all-files/io5/IoCheckmarkSharp';
import { Button } from '@chakra-ui/button'; import { Button } from '@chakra-ui/button';
import { IoCheckmarkSharp } from '@react-icons/all-files/io5/IoCheckmarkSharp';
import { IoCloseSharp } from '@react-icons/all-files/io5/IoCloseSharp';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
export default function EnableBtn(props) { export default function EnableBtn(props) {
@@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import { IconButton } from '@chakra-ui/button'; import { IconButton } from '@chakra-ui/button';
import { IoPause } from '@react-icons/all-files/io5/IoPause';
import { Tooltip } from '@chakra-ui/tooltip'; import { Tooltip } from '@chakra-ui/tooltip';
import { IoPause } from '@react-icons/all-files/io5/IoPause';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
export default function PauseIconBtn(props) { export default function PauseIconBtn(props) {
@@ -11,6 +11,7 @@ import {
import { Tooltip } from '@chakra-ui/tooltip'; import { Tooltip } from '@chakra-ui/tooltip';
import { FiPower } from '@react-icons/all-files/fi/FiPower'; import { FiPower } from '@react-icons/all-files/fi/FiPower';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { LoggingContext } from '../../../app/context/LoggingContext'; import { LoggingContext } from '../../../app/context/LoggingContext';
export default function QuitIconBtn(props) { export default function QuitIconBtn(props) {
@@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import { IconButton } from '@chakra-ui/button'; import { IconButton } from '@chakra-ui/button';
import { IoTimeOutline } from '@react-icons/all-files/io5/IoTimeOutline';
import { Tooltip } from '@chakra-ui/tooltip'; import { Tooltip } from '@chakra-ui/tooltip';
import { IoTimeOutline } from '@react-icons/all-files/io5/IoTimeOutline';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
export default function RollIconBtn(props) { export default function RollIconBtn(props) {
@@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import { IconButton } from '@chakra-ui/button'; import { IconButton } from '@chakra-ui/button';
import { IoPlay } from '@react-icons/all-files/io5/IoPlay';
import { Tooltip } from '@chakra-ui/tooltip'; import { Tooltip } from '@chakra-ui/tooltip';
import { IoPlay } from '@react-icons/all-files/io5/IoPlay';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
export default function StartIconBtn(props) { export default function StartIconBtn(props) {
@@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import { IconButton } from '@chakra-ui/button'; import { IconButton } from '@chakra-ui/button';
import { IoStop } from '@react-icons/all-files/io5/IoStop';
import { Tooltip } from '@chakra-ui/tooltip'; import { Tooltip } from '@chakra-ui/tooltip';
import { IoStop } from '@react-icons/all-files/io5/IoStop';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
export default function UnloadIconBtn(props) { export default function UnloadIconBtn(props) {
@@ -1,7 +1,8 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types';
import { Icon } from '@chakra-ui/react'; import { Icon } from '@chakra-ui/react';
import { FiChevronUp } from '@react-icons/all-files/fi/FiChevronUp'; import { FiChevronUp } from '@react-icons/all-files/fi/FiChevronUp';
import PropTypes from 'prop-types';
import style from './CollapseBar.module.scss'; import style from './CollapseBar.module.scss';
export default function CollapseBar(props) { export default function CollapseBar(props) {
@@ -1,9 +1,10 @@
import React, { memo } from 'react'; import React, { memo } from 'react';
import { formatDisplay } from 'common/utils/dateConfig'; import { formatDisplay } from 'common/utils/dateConfig';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import styles from './Countdown.module.scss';
const Countdown = ({ time, small, isNegative, hideZeroHours }) => { import styles from './TimerDisplay.module.scss';
const TimerDisplay = ({ time, small, isNegative, hideZeroHours }) => {
// prepare display string // prepare display string
const display = const display =
time != null && !isNaN(time) ? formatDisplay(time, hideZeroHours) : '-- : -- : --'; time != null && !isNaN(time) ? formatDisplay(time, hideZeroHours) : '-- : -- : --';
@@ -18,9 +19,9 @@ const Countdown = ({ time, small, isNegative, hideZeroHours }) => {
); );
}; };
export default memo(Countdown); export default memo(TimerDisplay);
Countdown.propTypes = { TimerDisplay.propTypes = {
time: PropTypes.number, time: PropTypes.number,
small: PropTypes.bool, small: PropTypes.bool,
isNegative: PropTypes.bool, isNegative: PropTypes.bool,
@@ -1,6 +1,8 @@
/* eslint-disable react/destructuring-assignment */ /* eslint-disable react/destructuring-assignment */
import React from 'react'; import React from 'react';
import { LoggingContext } from '../../../app/context/LoggingContext'; import { LoggingContext } from '../../../app/context/LoggingContext';
import style from './ErrorBoundary.module.scss'; import style from './ErrorBoundary.module.scss';
const appVersion = require('../../../../package.json').version; const appVersion = require('../../../../package.json').version;
@@ -1,8 +1,9 @@
import React, { useCallback, useContext } from 'react'; import React, { useCallback, useContext } from 'react';
import EditableTimer from 'common/input/EditableTimer'; import EditableTimer from 'common/input/EditableTimer';
import PropTypes from 'prop-types';
import { LoggingContext } from '../../../app/context/LoggingContext'; import { LoggingContext } from '../../../app/context/LoggingContext';
import { validateTimes } from '../../../app/entryValidator'; import { validateTimes } from '../../../app/entryValidator';
import PropTypes from 'prop-types';
export default function EventTimes(props) { export default function EventTimes(props) {
const { actionHandler, delay, timeStart, timeEnd, previousEnd } = props; const { actionHandler, delay, timeStart, timeEnd, previousEnd } = props;
@@ -1,9 +1,11 @@
import React, { useCallback, useContext } from 'react'; import React, { useCallback, useContext } from 'react';
import PropTypes from 'prop-types';
import { LoggingContext } from '../../../app/context/LoggingContext'; import { LoggingContext } from '../../../app/context/LoggingContext';
import { validateTimes } from '../../../app/entryValidator'; import { validateTimes } from '../../../app/entryValidator';
import PropTypes from 'prop-types';
import TimesDelayed from './TimesDelayed';
import Times from './Times'; import Times from './Times';
import TimesDelayed from './TimesDelayed';
export default function EventTimesVertical(props) { export default function EventTimesVertical(props) {
const { delay, timeStart, timeEnd, duration, previousEnd, actionHandler } = props; const { delay, timeStart, timeEnd, duration, previousEnd, actionHandler } = props;
@@ -1,6 +1,8 @@
import React from 'react'; import React from 'react';
import EditableTimer from '../../input/EditableTimer';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import EditableTimer from '../../input/EditableTimer';
import style from './Times.module.scss' import style from './Times.module.scss'
export default function Times(props) { export default function Times(props) {
@@ -1,7 +1,9 @@
import React from 'react'; import React from 'react';
import EditableTimer from '../../input/EditableTimer';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import EditableTimer from '../../input/EditableTimer';
import { stringFromMillis } from '../../utils/time'; import { stringFromMillis } from '../../utils/time';
import style from './Times.module.scss' import style from './Times.module.scss'
export default function TimesDelayed(props) { export default function TimesDelayed(props) {
@@ -1,6 +1,7 @@
import React from 'react'; import React from 'react';
import { clamp } from 'app/utils/math'; import { clamp } from 'app/utils/math';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import styles from './MyProgressBar.module.scss'; import styles from './MyProgressBar.module.scss';
export default function MyProgressBar(props) { export default function MyProgressBar(props) {
+16 -26
View File
@@ -1,12 +1,15 @@
import React, { useCallback, useEffect, useState } from 'react'; import React, { useCallback, useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { Image } from '@chakra-ui/react';
import { AnimatePresence, motion } from 'framer-motion';
import navlogo from 'assets/images/logos/LOGO-72.png';
import style from './NavLogo.module.scss';
import { IconButton } from '@chakra-ui/button'; import { IconButton } from '@chakra-ui/button';
import { Image } from '@chakra-ui/react';
import { IoExpand } from '@react-icons/all-files/io5/IoExpand'; import { IoExpand } from '@react-icons/all-files/io5/IoExpand';
import navlogo from 'assets/images/logos/LOGO-72.png';
import { AnimatePresence, motion } from 'framer-motion';
import PropTypes from 'prop-types';
import navigatorConstants from './navigatorConstants';
import style from './NavLogo.module.scss';
/* Styling for action buttons */ /* Styling for action buttons */
const navButtonStyle = { const navButtonStyle = {
@@ -91,27 +94,14 @@ export default function NavLogo(props) {
exit={{ opacity: 0, scaleY: 0, y: -50 }} exit={{ opacity: 0, scaleY: 0, y: -50 }}
className={style.nav} className={style.nav}
> >
<Link to='/timer' {...tabProps}> {navigatorConstants.map((route) => (
Timer <Link
</Link> to={route.url}
<Link to='/minimal' {...tabProps}> key={route.url}
Minimal Timer {...tabProps}>
</Link> {route.label}
<Link to='/sm' {...tabProps}> </Link>
Backstage ))}
</Link>
<Link to='/public' {...tabProps}>
Public
</Link>
<Link to='/lower' {...tabProps}>
Lower Thirds
</Link>
<Link to='/pip' {...tabProps}>
PIP
</Link>
<Link to='/studio' {...tabProps}>
Studio Clock
</Link>
</motion.div> </motion.div>
</> </>
)} )}
@@ -0,0 +1,12 @@
const navigatorConstants = [
{ url: '/timer', label: 'Timer' },
{ url: '/minimal', label: 'Minimal Timer' },
{ url: '/sm', label: 'Backstage' },
{ url: '/public', label: 'Public' },
{ url: '/lower', label: 'Lower Thirds' },
{ url: '/pip', label: 'PiP' },
{ url: '/studio', label: 'Studio Clock' },
{ url: '/countdown', label: 'Countdown' },
];
export default navigatorConstants;
@@ -1,9 +1,11 @@
import React, { useCallback, useContext, useEffect, useState } from 'react'; import React, { useCallback, useContext, useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import { HStack, PinInput, PinInputField } from '@chakra-ui/react';
import { IconButton } from '@chakra-ui/button'; import { IconButton } from '@chakra-ui/button';
import { HStack, PinInput, PinInputField } from '@chakra-ui/react';
import { FiCheck } from '@react-icons/all-files/fi/FiCheck'; import { FiCheck } from '@react-icons/all-files/fi/FiCheck';
import PropTypes from 'prop-types';
import { AppContext } from '../../../app/context/AppContext'; import { AppContext } from '../../../app/context/AppContext';
import style from './ProtectRoute.module.scss'; import style from './ProtectRoute.module.scss';
export default function ProtectRoute({ children }) { export default function ProtectRoute({ children }) {
@@ -1,8 +1,11 @@
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import TodayItem from './TodayItem';
import { useInterval } from 'app/hooks/useInterval'; import { useInterval } from 'app/hooks/useInterval';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import Empty from '../../state/Empty'; import Empty from '../../state/Empty';
import TodayItem from './TodayItem';
import style from './Paginator.module.scss'; import style from './Paginator.module.scss';
export default function Paginator(props) { export default function Paginator(props) {
@@ -1,5 +1,6 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import style from './TitleCard.module.scss'; import style from './TitleCard.module.scss';
export default function TitleCard(props) { export default function TitleCard(props) {
@@ -1,5 +1,6 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import style from './TitleSide.module.scss'; import style from './TitleSide.module.scss';
export default function TitleSide(props) { export default function TitleSide(props) {
@@ -1,6 +1,8 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { stringFromMillis } from '../../utils/time'; import { stringFromMillis } from '../../utils/time';
import style from './Paginator.module.scss'; import style from './Paginator.module.scss';
export default function TodayItem(props) { export default function TodayItem(props) {
+4 -2
View File
@@ -1,9 +1,11 @@
import React, { useCallback, useEffect, useState } from 'react'; import React, { useCallback, useEffect, useState } from 'react';
import { Editable, EditableInput, EditablePreview } from '@chakra-ui/react'; import { Editable, EditableInput, EditablePreview } from '@chakra-ui/react';
import { clamp } from '../../app/utils/math';
import style from './TimeInput.module.css';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { clamp } from '../../app/utils/math';
import style from './TimeInput.module.css';
const inputProps = { const inputProps = {
width: 20, width: 20,
fontWeight: 400, fontWeight: 400,
+2 -1
View File
@@ -1,8 +1,9 @@
import React, { useCallback, useEffect, useState } from 'react'; import React, { useCallback, useEffect, useState } from 'react';
import { Editable, EditableInput, EditablePreview } from '@chakra-ui/editable'; import { Editable, EditableInput, EditablePreview } from '@chakra-ui/editable';
import style from './EditableText.module.scss';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import style from './EditableText.module.scss';
export default function EditableText(props) { export default function EditableText(props) {
const { label, defaultValue, placeholder, submitHandler, maxchar = 40, ...rest } = props; const { label, defaultValue, placeholder, submitHandler, maxchar = 40, ...rest } = props;
const [text, setText] = useState(defaultValue || ''); const [text, setText] = useState(defaultValue || '');
+4 -2
View File
@@ -1,9 +1,11 @@
import React, { useCallback, useContext, useEffect, useState } from 'react'; import React, { useCallback, useContext, useEffect, useState } from 'react';
import { Editable, EditableInput, EditablePreview } from '@chakra-ui/editable'; import { Editable, EditableInput, EditablePreview } from '@chakra-ui/editable';
import { forgivingStringToMillis } from '../utils/dateConfig';
import { LoggingContext } from '../../app/context/LoggingContext';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { LoggingContext } from '../../app/context/LoggingContext';
import { forgivingStringToMillis } from '../utils/dateConfig';
import { stringFromMillis } from '../utils/time'; import { stringFromMillis } from '../utils/time';
import style from './EditableTimer.module.scss'; import style from './EditableTimer.module.scss';
export default function EditableTimer(props) { export default function EditableTimer(props) {
@@ -1,6 +1,7 @@
import React from 'react'; import React from 'react';
import { render, screen } from '@testing-library/react'; import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event'; import userEvent from '@testing-library/user-event';
import EditableTimer from '../EditableTimer'; import EditableTimer from '../EditableTimer';
const renderEditableTimer = ( const renderEditableTimer = (
+4 -2
View File
@@ -1,12 +1,13 @@
import React from 'react'; import React from 'react';
import { ReactComponent as Emptyimage } from 'assets/images/empty.svg'; import { ReactComponent as Emptyimage } from 'assets/images/empty.svg';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import style from './Empty.module.scss'; import style from './Empty.module.scss';
export default function Empty(props) { export default function Empty(props) {
const { text, ...rest } = props; const { text, dark, ...rest } = props;
return ( return (
<div className={style.emptyContainer} {...rest}> <div className={`${style.emptyContainer} ${dark ? style.dark : ''}`} {...rest}>
<Emptyimage className={style.empty} /> <Emptyimage className={style.empty} />
<span className={style.text}>{text}</span> <span className={style.text}>{text}</span>
</div> </div>
@@ -15,4 +16,5 @@ export default function Empty(props) {
Empty.propTypes = { Empty.propTypes = {
text: PropTypes.string, text: PropTypes.string,
dark: PropTypes.bool,
} }
+20 -10
View File
@@ -2,16 +2,26 @@
.emptyContainer { .emptyContainer {
width: 100%; width: 100%;
height: 100%;
text-align: center; text-align: center;
}
.empty {
width: 100%;
opacity: 0.3;
}
.text {
color: $bg-black-300; color: $bg-black-300;
font-weight: 600;
font-size: 2em; .empty {
width: 100%;
opacity: 0.3;
}
.text {
font-weight: 600;
font-size: 2em;
}
&.dark {
background: $bg-black;
color: $bg-gray-500;
.empty {
opacity: 1;
}
}
} }
@@ -14,6 +14,11 @@ describe('test string from formatDisplay function', () => {
expect(formatDisplay(t.val, false)).toBe(t.result); expect(formatDisplay(t.val, false)).toBe(t.result);
}); });
it('test with not numbers', () => {
const t = { val: 'test', result: '00:00:00' };
expect(formatDisplay(t.val, false)).toBe(t.result);
});
it('test with valid millis', () => { it('test with valid millis', () => {
const t = { val: 3600, result: '01:00:00' }; const t = { val: 3600, result: '01:00:00' };
expect(formatDisplay(t.val, false)).toBe(t.result); expect(formatDisplay(t.val, false)).toBe(t.result);
@@ -0,0 +1,56 @@
import getDelayTo from '../getDelayTo';
describe('getDelayTo function', () => {
it('handles list with delays', () => {
const delayDuration = 100;
const events = [
{ type: 'event' },
{ type: 'delay', duration: delayDuration },
{ type: 'event' },
];
const notDelayed = getDelayTo(events, 0);
expect(notDelayed).toBe(0);
const delayedEvent = getDelayTo(events, 2);
expect(delayedEvent).toBe(delayDuration);
});
it('handles list without delays', () => {
const events = [{ type: 'event' }, { type: 'event' }];
const notDelayed = getDelayTo(events, 1);
expect(notDelayed).toBe(0);
});
it('handles list with multiple delays', () => {
const delayDuration = 100;
const events = [
{ type: 'event' },
{ type: 'delay', duration: delayDuration },
{ type: 'event' },
{ type: 'delay', duration: delayDuration },
{ type: 'event' },
];
const doubleDelay = getDelayTo(events, 4);
expect(doubleDelay).toBe(delayDuration * 2);
});
it('handles list with blocks', () => {
const events = [
{ type: 'event' },
{ type: 'delay', duration: 100 },
{ type: 'event' },
{ type: 'block' },
{ type: 'event' },
];
const notDelayed = getDelayTo(events, 4);
expect(notDelayed).toBe(0);
});
it('handles index greater than list', () => {
const events = [{ type: 'event' }, { type: 'delay', duration: 100 }, { type: 'event' }];
const notDelayed = getDelayTo(events, 3);
expect(notDelayed).toBe(0);
});
it('handles negative index (not found)', () => {
const events = [{ type: 'event' }, { type: 'delay', duration: 100 }, { type: 'event' }];
const notDelayed = getDelayTo(events, -1);
expect(notDelayed).toBe(0);
});
});
+4
View File
@@ -13,6 +13,10 @@ const mth = 1000 * 60 * 60; // millis to hours
* @returns {string} String representing absolute time 00:12:02 * @returns {string} String representing absolute time 00:12:02
*/ */
export function formatDisplay(seconds, hideZero = false) { export function formatDisplay(seconds, hideZero = false) {
if (typeof seconds !== 'number') {
return hideZero ? '00:00' : '00:00:00';
}
// add an extra 0 if necessary // add an extra 0 if necessary
const format = (val) => `0${Math.floor(val)}`.slice(-2); const format = (val) => `0${Math.floor(val)}`.slice(-2);
+25
View File
@@ -0,0 +1,25 @@
/**
* @description calculates delay to a given event
* @param {array} events
* @param {number} eventIndex
* @return {number} - delay value of given event
*/
export default function getDelayTo(events, eventIndex) {
let delay = 0;
let index = 0;
if (eventIndex >= 0) {
for (const event of events) {
if (eventIndex === index) {
return delay;
}
if (event.type === 'delay') {
delay += event.duration;
} else if (event.type === 'block') {
delay = 0;
}
index++;
}
}
return 0;
}
+3 -1
View File
@@ -1,6 +1,8 @@
import React from 'react'; import React from 'react';
import ProtectRoute from '../common/components/protectRoute/ProtectRoute';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import ProtectRoute from '../common/components/protectRoute/ProtectRoute';
import style from './FeatureWrapper.module.scss'; import style from './FeatureWrapper.module.scss';
export default function FeatureWrapper({ children }) { export default function FeatureWrapper({ children }) {
@@ -1,6 +1,7 @@
import React from 'react'; import React from 'react';
import { render, screen } from '@testing-library/react'; import { render, screen } from '@testing-library/react';
import SocketProvider from 'app/context/socketContext'; import SocketProvider from 'app/context/socketContext';
import MessageControl from '../message/MessageControl'; import MessageControl from '../message/MessageControl';
// need to inject the socket provider to make component // need to inject the socket provider to make component
@@ -1,6 +1,7 @@
import React from 'react'; import React from 'react';
import { render, screen } from '@testing-library/react'; import { render, screen } from '@testing-library/react';
import SocketProvider from 'app/context/socketContext'; import SocketProvider from 'app/context/socketContext';
import PlaybackControl from '../playback/PlaybackControl'; import PlaybackControl from '../playback/PlaybackControl';
test('check that playback control renders', async () => { test('check that playback control renders', async () => {
@@ -1,9 +1,10 @@
import React from 'react'; import React from 'react';
import { IconButton } from '@chakra-ui/button';
import { Editable, EditableInput, EditablePreview } from '@chakra-ui/editable'; import { Editable, EditableInput, EditablePreview } from '@chakra-ui/editable';
import { Tooltip } from '@chakra-ui/tooltip'; import { Tooltip } from '@chakra-ui/tooltip';
import { IconButton } from '@chakra-ui/button';
import { IoSunny } from '@react-icons/all-files/io5/IoSunny'; import { IoSunny } from '@react-icons/all-files/io5/IoSunny';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import style from './MessageControl.module.scss'; import style from './MessageControl.module.scss';
export default function InputRow(props) { export default function InputRow(props) {
@@ -1,10 +1,12 @@
import React, { useCallback, useEffect, useState } from 'react'; import React, { useCallback, useEffect, useState } from 'react';
import { useSocket } from 'app/context/socketContext';
import InputRow from './InputRow';
import { Tooltip } from '@chakra-ui/tooltip';
import { IconButton } from '@chakra-ui/button'; import { IconButton } from '@chakra-ui/button';
import { IoMicSharp } from '@react-icons/all-files/io5/IoMicSharp'; import { Tooltip } from '@chakra-ui/tooltip';
import { IoMicOffOutline } from '@react-icons/all-files/io5/IoMicOffOutline'; import { IoMicOffOutline } from '@react-icons/all-files/io5/IoMicOffOutline';
import { IoMicSharp } from '@react-icons/all-files/io5/IoMicSharp';
import { useSocket } from 'app/context/socketContext';
import InputRow from './InputRow';
import style from './MessageControl.module.scss'; import style from './MessageControl.module.scss';
export default function MessageControl() { export default function MessageControl() {
@@ -1,11 +1,14 @@
import React from 'react'; import React from 'react';
import { Box } from '@chakra-ui/layout'; import { Box } from '@chakra-ui/layout';
import ErrorBoundary from '../../../common/components/errorBoundary/ErrorBoundary';
import MessageControl from './MessageControl';
import style from '../../editors/Editor.module.scss';
import { FiArrowUpRight } from '@react-icons/all-files/fi/FiArrowUpRight'; import { FiArrowUpRight } from '@react-icons/all-files/fi/FiArrowUpRight';
import ErrorBoundary from '../../../common/components/errorBoundary/ErrorBoundary';
import { handleLinks } from '../../../common/utils/linkUtils'; import { handleLinks } from '../../../common/utils/linkUtils';
import MessageControl from './MessageControl';
import style from '../../editors/Editor.module.scss';
export default function MessageControlExport() { export default function MessageControlExport() {
return ( return (
<Box className={style.messages}> <Box className={style.messages}>
@@ -1,8 +1,10 @@
import React from 'react'; import React from 'react';
import StartIconBtn from '../../../common/components/buttons/StartIconBtn'; import PropTypes from 'prop-types';
import PauseIconBtn from '../../../common/components/buttons/PauseIconBtn'; import PauseIconBtn from '../../../common/components/buttons/PauseIconBtn';
import RollIconBtn from '../../../common/components/buttons/RollIconBtn'; import RollIconBtn from '../../../common/components/buttons/RollIconBtn';
import PropTypes from 'prop-types'; import StartIconBtn from '../../../common/components/buttons/StartIconBtn';
import style from './PlaybackControl.module.scss'; import style from './PlaybackControl.module.scss';
export default function Playback(props) { export default function Playback(props) {
@@ -1,7 +1,8 @@
import React, { memo } from 'react'; import React, { memo } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import Transport from './Transport';
import Playback from './Playback'; import Playback from './Playback';
import Transport from './Transport';
const areEqual = (prevProps, nextProps) => { const areEqual = (prevProps, nextProps) => {
return ( return (
@@ -1,9 +1,11 @@
import React, { useCallback, useEffect, useState } from 'react'; import React, { useCallback, useEffect, useState } from 'react';
import style from './PlaybackControl.module.scss';
import { useSocket } from 'app/context/socketContext'; import { useSocket } from 'app/context/socketContext';
import PlaybackButtons from './PlaybackButtons'; import PlaybackButtons from './PlaybackButtons';
import PlaybackTimer from './PlaybackTimer'; import PlaybackTimer from './PlaybackTimer';
import style from './PlaybackControl.module.scss';
export default function PlaybackControl() { export default function PlaybackControl() {
const socket = useSocket(); const socket = useSocket();
const [playback, setPlayback] = useState(null); const [playback, setPlayback] = useState(null);
@@ -1,9 +1,11 @@
import React, { memo } from 'react'; import React, { memo } from 'react';
import Countdown from 'common/components/countdown/Countdown';
import { Tooltip } from '@chakra-ui/react';
import { Button } from '@chakra-ui/button'; import { Button } from '@chakra-ui/button';
import { Tooltip } from '@chakra-ui/react';
import TimerDisplay from 'common/components/countdown/TimerDisplay';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { stringFromMillis } from '../../../common/utils/time'; import { stringFromMillis } from '../../../common/utils/time';
import style from './PlaybackControl.module.scss'; import style from './PlaybackControl.module.scss';
const areEqual = (prevProps, nextProps) => { const areEqual = (prevProps, nextProps) => {
@@ -43,7 +45,7 @@ const PlaybackTimer = (props) => {
<div className={style.indDelay} /> <div className={style.indDelay} />
</div> </div>
<div className={style.timer}> <div className={style.timer}>
<Countdown <TimerDisplay
time={isWaiting ? timer.secondary : timer.running} time={isWaiting ? timer.secondary : timer.running}
isNegative={timer.isNegative} isNegative={timer.isNegative}
small small
@@ -1,18 +1,20 @@
import React from 'react'; import React from 'react';
import { Box } from '@chakra-ui/layout'; import { Box } from '@chakra-ui/layout';
import ErrorBoundary from '../../../common/components/errorBoundary/ErrorBoundary';
import PlaybackControl from './PlaybackControl';
import styles from '../../editors/Editor.module.scss';
import style from '../../editors/Editor.module.scss';
import { FiArrowUpRight } from '@react-icons/all-files/fi/FiArrowUpRight'; import { FiArrowUpRight } from '@react-icons/all-files/fi/FiArrowUpRight';
import ErrorBoundary from '../../../common/components/errorBoundary/ErrorBoundary';
import { handleLinks } from '../../../common/utils/linkUtils'; import { handleLinks } from '../../../common/utils/linkUtils';
import PlaybackControl from './PlaybackControl';
import style from '../../editors/Editor.module.scss';
export default function TimerControlExport() { export default function TimerControlExport() {
return ( return (
<Box className={styles.playback}> <Box className={style.playback}>
<h1>Timer Control</h1> <h1>Timer Control</h1>
<FiArrowUpRight className={style.corner} onClick={(event) => handleLinks(event, 'timercontrol')} /> <FiArrowUpRight className={style.corner} onClick={(event) => handleLinks(event, 'timercontrol')} />
<div className={styles.content}> <div className={style.content}>
<ErrorBoundary> <ErrorBoundary>
<PlaybackControl /> <PlaybackControl />
</ErrorBoundary> </ErrorBoundary>
@@ -1,11 +1,13 @@
import React from 'react'; import React from 'react';
import { IoArrowUndo } from '@react-icons/all-files/io5/IoArrowUndo';
import { IoPlaySkipBack } from '@react-icons/all-files/io5/IoPlaySkipBack'; import { IoPlaySkipBack } from '@react-icons/all-files/io5/IoPlaySkipBack';
import { IoPlaySkipForward } from '@react-icons/all-files/io5/IoPlaySkipForward'; import { IoPlaySkipForward } from '@react-icons/all-files/io5/IoPlaySkipForward';
import { IoArrowUndo } from '@react-icons/all-files/io5/IoArrowUndo';
import UnloadIconBtn from '../../../common/components/buttons/UnloadIconBtn';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import style from './PlaybackControl.module.scss';
import TransportIconBtn from '../../../common/components/buttons/TransportIconBtn'; import TransportIconBtn from '../../../common/components/buttons/TransportIconBtn';
import UnloadIconBtn from '../../../common/components/buttons/UnloadIconBtn';
import style from './PlaybackControl.module.scss';
export default function Transport(props) { export default function Transport(props) {
const { playback, selectedId, playbackControl, noEvents } = props; const { playback, selectedId, playbackControl, noEvents } = props;
@@ -1,11 +1,13 @@
import React from 'react'; import React from 'react';
import { HStack } from '@chakra-ui/react';
import { Draggable } from 'react-beautiful-dnd'; import { Draggable } from 'react-beautiful-dnd';
import { IoRemove } from '@react-icons/all-files/io5/IoRemove'; import { HStack } from '@chakra-ui/react';
import { FiMoreVertical } from '@react-icons/all-files/fi/FiMoreVertical'; import { FiMoreVertical } from '@react-icons/all-files/fi/FiMoreVertical';
import { IoRemove } from '@react-icons/all-files/io5/IoRemove';
import PropTypes from 'prop-types';
import ActionButtons from '../../../common/components/buttons/ActionButtons'; import ActionButtons from '../../../common/components/buttons/ActionButtons';
import TooltipLoadingActionBtn from '../../../common/components/buttons/TooltipLoadingActionBtn'; import TooltipLoadingActionBtn from '../../../common/components/buttons/TooltipLoadingActionBtn';
import PropTypes from 'prop-types';
import style from './BlockBlock.module.scss'; import style from './BlockBlock.module.scss';
export default function BlockBlock(props) { export default function BlockBlock(props) {
@@ -1,16 +1,18 @@
import React, { useCallback } from 'react'; import React, { useCallback } from 'react';
import { HStack } from '@chakra-ui/react';
import { Draggable } from 'react-beautiful-dnd'; import { Draggable } from 'react-beautiful-dnd';
import { millisToMinutes } from 'common/utils/dateConfig'; import { HStack } from '@chakra-ui/react';
import { IoRemove } from '@react-icons/all-files/io5/IoRemove';
import { FiCheck } from '@react-icons/all-files/fi/FiCheck'; import { FiCheck } from '@react-icons/all-files/fi/FiCheck';
import { FiMoreVertical } from '@react-icons/all-files/fi/FiMoreVertical'; import { FiMoreVertical } from '@react-icons/all-files/fi/FiMoreVertical';
import ActionButtons from '../../../common/components/buttons/ActionButtons'; import { IoRemove } from '@react-icons/all-files/io5/IoRemove';
import DelayInput from 'common/input/DelayInput'; import DelayInput from 'common/input/DelayInput';
import { millisToMinutes } from 'common/utils/dateConfig';
import PropTypes from 'prop-types';
import ActionButtons from '../../../common/components/buttons/ActionButtons';
import TooltipActionBtn from '../../../common/components/buttons/TooltipActionBtn'; import TooltipActionBtn from '../../../common/components/buttons/TooltipActionBtn';
import TooltipLoadingActionBtn from '../../../common/components/buttons/TooltipLoadingActionBtn'; import TooltipLoadingActionBtn from '../../../common/components/buttons/TooltipLoadingActionBtn';
import style from './DelayBlock.module.scss'; import style from './DelayBlock.module.scss';
import PropTypes from 'prop-types';
export default function DelayBlock(props) { export default function DelayBlock(props) {
const { eventsHandler, data, index, actionHandler } = props; const { eventsHandler, data, index, actionHandler } = props;
+6 -4
View File
@@ -1,11 +1,13 @@
import React, { lazy, useEffect } from 'react'; import React, { lazy, useEffect } from 'react';
import { useDisclosure } from '@chakra-ui/hooks'; import { useDisclosure } from '@chakra-ui/hooks';
import ModalManager from 'features/modals/ModalManager';
import ErrorBoundary from 'common/components/errorBoundary/ErrorBoundary';
import { LoggingProvider } from '../../app/context/LoggingContext';
import { LocalEventSettingsProvider } from '../../app/context/LocalEventSettingsContext';
import { Box } from '@chakra-ui/layout'; import { Box } from '@chakra-ui/layout';
import ErrorBoundary from 'common/components/errorBoundary/ErrorBoundary';
import ModalManager from 'features/modals/ModalManager';
import { LocalEventSettingsProvider } from '../../app/context/LocalEventSettingsContext';
import { LoggingProvider } from '../../app/context/LoggingContext';
import MenuBar from '../menu/MenuBar'; import MenuBar from '../menu/MenuBar';
import styles from './Editor.module.scss'; import styles from './Editor.module.scss';
const EventList = lazy(() => import('features/editors/list/EventListExport')); const EventList = lazy(() => import('features/editors/list/EventListExport'));
+74 -92
View File
@@ -9,6 +9,12 @@
color: $ontime-pink; color: $ontime-pink;
} }
h1 {
font-size: max(1.5em, 16px);
color: $bg-gray-100;
padding-bottom: 0.25em;
}
.mainContainer { .mainContainer {
background: $bg-black; background: $bg-black;
width: 100%; width: 100%;
@@ -38,89 +44,6 @@
} }
} }
/* 2/3 window, hide info */
@media (max-width: 1450px) and (min-height: 700px) {
.mainContainer {
height: 100%;
grid-template-rows: auto 1fr;
grid-template-columns: 40px 48em auto;
/* grid-template-areas:
'even play sett'
'even mess sett'; */
}
.info {
visibility: hidden;
}
}
/* 1/2 window, event list only */
@media (max-width: 1100px) {
.mainContainer {
height: 100%;
grid-template-rows: 1fr auto;
grid-template-columns: 40px 48em;
/* grid-template-areas:
'sett even '
'sett play '; */
}
.info,
.messages,
.playback {
visibility: hidden;
}
}
/* 1/3 window, show control only */
@media (max-width: 850px) and (min-height: 500px) {
.mainContainer {
grid-template-rows: auto 1fr;
grid-template-columns: 100%;
column-gap: 0;
grid-template-areas:
'play'
'mess';
}
.playback,
.messages {
visibility: visible;
}
.editor,
.info,
.settings {
visibility: hidden;
}
}
/* 1/3 corner window, playback only */
@media (max-width: 850px) and (max-height: 500px) {
.mainContainer {
grid-template-rows: 100%;
grid-template-columns: 100%;
grid-template-areas: 'play';
}
.playback {
visibility: visible;
}
.editor,
.messages,
.info,
.settings {
visibility: hidden;
}
}
h1 {
font-size: max(1.5em, 16px);
color: $bg-gray-100;
padding-bottom: 0.25em;
}
.mainContainer > div { .mainContainer > div {
border-radius: 0.5em; border-radius: 0.5em;
height: 100%; height: 100%;
@@ -184,15 +107,74 @@ h1 {
padding-top: 0.5em; padding-top: 0.5em;
} }
.cornerButtonContainer {
position: relative; /* 2/3 window, hide info */
top: -4.5em; @media (max-width: 1450px) and (min-width: 1101px) {
display: flex; .mainContainer {
justify-content: flex-end; height: 100%;
grid-template-rows: auto 1fr;
grid-template-columns: 40px 48em auto;
.info {
visibility: hidden;
}
}
} }
.buttonContainer { /* 1/2 window, event list only */
padding-bottom: 2em; @media (max-width: 1100px) and (min-width: 851px){
display: flex; .mainContainer {
justify-content: flex-end; height: 100%;
grid-template-rows: 1fr auto;
grid-template-columns: 40px 48em;
.info,
.messages,
.playback {
visibility: hidden;
}
}
}
/* 1/3 window, show control only */
@media (max-width: 850px) and (min-height: 500px) {
.mainContainer {
grid-template-rows: auto 1fr;
grid-template-columns: 100%;
column-gap: 0;
grid-template-areas:
'play'
'mess';
.playback,
.messages {
visibility: visible;
}
.editor,
.info,
.settings {
visibility: hidden;
}
}
}
/* 1/3 corner window, playback only */
@media (max-width: 850px) and (max-height: 500px) {
.mainContainer {
grid-template-rows: 100%;
grid-template-columns: 100%;
grid-template-areas: 'play';
.playback {
visibility: visible;
}
.editor,
.messages,
.info,
.settings {
visibility: hidden;
}
}
} }
@@ -1,8 +1,10 @@
import React, { useContext, useEffect, useState } from 'react'; import React, { useContext, useEffect, useState } from 'react';
import { Tooltip } from '@chakra-ui/tooltip';
import { Checkbox } from '@chakra-ui/react'; import { Checkbox } from '@chakra-ui/react';
import { LocalEventSettingsContext } from '../../../app/context/LocalEventSettingsContext'; import { Tooltip } from '@chakra-ui/tooltip';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { LocalEventSettingsContext } from '../../../app/context/LocalEventSettingsContext';
import style from './EntryBlock.module.scss'; import style from './EntryBlock.module.scss';
export default function EntryBlock(props) { export default function EntryBlock(props) {
@@ -1,11 +1,13 @@
import React, { memo } from 'react'; import React, { memo } from 'react';
import { HStack } from '@chakra-ui/react'; import { HStack } from '@chakra-ui/react';
import { FiMoreVertical } from '@react-icons/all-files/fi/FiMoreVertical'; import { FiMoreVertical } from '@react-icons/all-files/fi/FiMoreVertical';
import PropTypes from 'prop-types';
import ActionButtons from '../../../common/components/buttons/ActionButtons'; import ActionButtons from '../../../common/components/buttons/ActionButtons';
import PublicIconBtn from '../../../common/components/buttons/PublicIconBtn';
import EventTimes from '../../../common/components/eventTimes/EventTimes'; import EventTimes from '../../../common/components/eventTimes/EventTimes';
import EditableText from '../../../common/input/EditableText'; import EditableText from '../../../common/input/EditableText';
import PublicIconBtn from '../../../common/components/buttons/PublicIconBtn';
import PropTypes from 'prop-types';
import style from './EventBlock.module.scss'; import style from './EventBlock.module.scss';
const areEqual = (prevProps, nextProps) => { const areEqual = (prevProps, nextProps) => {
@@ -1,12 +1,15 @@
import React, { useContext, useMemo } from 'react'; import React, { useContext, useMemo } from 'react';
import { Draggable } from 'react-beautiful-dnd';
import Icon from '@chakra-ui/icon'; import Icon from '@chakra-ui/icon';
import { FiChevronUp } from '@react-icons/all-files/fi/FiChevronUp'; import { FiChevronUp } from '@react-icons/all-files/fi/FiChevronUp';
import { Draggable } from 'react-beautiful-dnd';
import { millisToMinutes } from 'common/utils/dateConfig'; import { millisToMinutes } from 'common/utils/dateConfig';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { CollapseContext } from '../../../app/context/CollapseContext'; import { CollapseContext } from '../../../app/context/CollapseContext';
import CollapsedBlock from './CollapsedBlock'; import CollapsedBlock from './CollapsedBlock';
import ExpandedBlock from './ExpandedBlock'; import ExpandedBlock from './ExpandedBlock';
import style from './EventBlock.module.scss'; import style from './EventBlock.module.scss';
export default function EventBlock(props) { export default function EventBlock(props) {
@@ -1,13 +1,15 @@
import React, { memo } from 'react'; import React, { memo } from 'react';
import { VStack } from '@chakra-ui/react'; import { VStack } from '@chakra-ui/react';
import { IoRemove } from '@react-icons/all-files/io5/IoRemove';
import { FiMoreVertical } from '@react-icons/all-files/fi/FiMoreVertical'; import { FiMoreVertical } from '@react-icons/all-files/fi/FiMoreVertical';
import { IoRemove } from '@react-icons/all-files/io5/IoRemove';
import PropTypes from 'prop-types';
import ActionButtons from '../../../common/components/buttons/ActionButtons'; import ActionButtons from '../../../common/components/buttons/ActionButtons';
import EventTimesVertical from '../../../common/components/eventTimes/EventTimesVertical';
import EditableText from '../../../common/input/EditableText';
import PublicIconBtn from '../../../common/components/buttons/PublicIconBtn'; import PublicIconBtn from '../../../common/components/buttons/PublicIconBtn';
import TooltipLoadingActionBtn from '../../../common/components/buttons/TooltipLoadingActionBtn'; import TooltipLoadingActionBtn from '../../../common/components/buttons/TooltipLoadingActionBtn';
import PropTypes from 'prop-types'; import EventTimesVertical from '../../../common/components/eventTimes/EventTimesVertical';
import EditableText from '../../../common/input/EditableText';
import style from './EventBlock.module.scss'; import style from './EventBlock.module.scss';
const areEqual = (prevProps, nextProps) => { const areEqual = (prevProps, nextProps) => {
@@ -1,5 +1,7 @@
import React from 'react'; import React from 'react';
import ProtectRoute from '../../common/components/protectRoute/ProtectRoute'; import ProtectRoute from '../../common/components/protectRoute/ProtectRoute';
import Editor from './Editor'; import Editor from './Editor';
export default function ProtectedEditor() { export default function ProtectedEditor() {
@@ -1,12 +1,15 @@
import React, { createRef, useCallback, useContext, useEffect, useState } from 'react'; import React, { createRef, useCallback, useContext, useEffect, useState } from 'react';
import style from './List.module.scss'; import { DragDropContext, Droppable } from 'react-beautiful-dnd';
import { useSocket } from 'app/context/socketContext'; import { useSocket } from 'app/context/socketContext';
import Empty from 'common/state/Empty'; import Empty from 'common/state/Empty';
import EventListItem from './EventListItem';
import { DragDropContext, Droppable } from 'react-beautiful-dnd';
import EntryBlock from '../EntryBlock/EntryBlock';
import { CursorContext } from '../../../app/context/CursorContext'; import { CursorContext } from '../../../app/context/CursorContext';
import { LocalEventSettingsContext } from '../../../app/context/LocalEventSettingsContext'; import { LocalEventSettingsContext } from '../../../app/context/LocalEventSettingsContext';
import EntryBlock from '../EntryBlock/EntryBlock';
import EventListItem from './EventListItem';
import style from './List.module.scss';
export default function EventList(props) { export default function EventList(props) {
const { events, eventsHandler } = props; const { events, eventsHandler } = props;
@@ -1,11 +1,14 @@
import React from 'react'; import React from 'react';
import { CursorProvider } from '../../../app/context/CursorContext';
import { CollapseProvider } from '../../../app/context/CollapseContext';
import { Box } from '@chakra-ui/layout'; import { Box } from '@chakra-ui/layout';
import ErrorBoundary from '../../../common/components/errorBoundary/ErrorBoundary';
import EventListWrapper from './EventListWrapper';
import { FiArrowUpRight } from '@react-icons/all-files/fi/FiArrowUpRight'; import { FiArrowUpRight } from '@react-icons/all-files/fi/FiArrowUpRight';
import { CollapseProvider } from '../../../app/context/CollapseContext';
import { CursorProvider } from '../../../app/context/CursorContext';
import ErrorBoundary from '../../../common/components/errorBoundary/ErrorBoundary';
import { handleLinks } from '../../../common/utils/linkUtils'; import { handleLinks } from '../../../common/utils/linkUtils';
import EventListWrapper from './EventListWrapper';
import style from '../Editor.module.scss'; import style from '../Editor.module.scss';
export default function EventListExport() { export default function EventListExport() {
@@ -1,11 +1,12 @@
import React, { memo, useCallback, useContext } from 'react'; import React, { memo, useCallback, useContext } from 'react';
import DelayBlock from '../DelayBlock/DelayBlock';
import BlockBlock from '../BlockBlock/BlockBlock';
import EventBlock from '../EventBlock/EventBlock';
import { LoggingContext } from '../../../app/context/LoggingContext';
import { LocalEventSettingsContext } from '../../../app/context/LocalEventSettingsContext';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { LocalEventSettingsContext } from '../../../app/context/LocalEventSettingsContext';
import { LoggingContext } from '../../../app/context/LoggingContext';
import BlockBlock from '../BlockBlock/BlockBlock';
import DelayBlock from '../DelayBlock/DelayBlock';
import EventBlock from '../EventBlock/EventBlock';
const areEqual = (prevProps, nextProps) => { const areEqual = (prevProps, nextProps) => {
return ( return (
prevProps.data.revision === nextProps.data.revision && prevProps.data.revision === nextProps.data.revision &&
@@ -1,7 +1,6 @@
import React, { useCallback, useContext, useEffect, useState } from 'react'; import React, { useCallback, useContext, useEffect, useState } from 'react';
import { useMutation, useQueryClient } from 'react-query'; import { useMutation, useQueryClient } from 'react-query';
import { EVENTS_TABLE } from 'app/api/apiConstants'; import { EVENTS_TABLE } from 'app/api/apiConstants';
import { LoggingContext } from '../../../app/context/LoggingContext';
import { import {
fetchAllEvents, fetchAllEvents,
requestApplyDelay, requestApplyDelay,
@@ -13,10 +12,14 @@ import {
requestReorder, requestReorder,
} from 'app/api/eventsApi.js'; } from 'app/api/eventsApi.js';
import { useFetch } from 'app/hooks/useFetch.js'; import { useFetch } from 'app/hooks/useFetch.js';
import EventList from './EventList';
import EventListMenu from 'features/menu/EventListMenu.jsx';
import Empty from 'common/state/Empty'; import Empty from 'common/state/Empty';
import EventListMenu from 'features/menu/EventListMenu.jsx';
import { CollapseContext } from '../../../app/context/CollapseContext'; import { CollapseContext } from '../../../app/context/CollapseContext';
import { LoggingContext } from '../../../app/context/LoggingContext';
import EventList from './EventList';
import styles from '../Editor.module.scss'; import styles from '../Editor.module.scss';
export default function EventListWrapper() { export default function EventListWrapper() {
+5 -3
View File
@@ -1,9 +1,11 @@
import React, { useState, useEffect } from 'react'; import React, { useEffect,useState } from 'react';
import { useSocket } from 'app/context/socketContext'; import { useSocket } from 'app/context/socketContext';
import style from './Info.module.scss';
import InfoTitle from './InfoTitle';
import InfoLogger from './InfoLogger'; import InfoLogger from './InfoLogger';
import InfoNif from './InfoNif'; import InfoNif from './InfoNif';
import InfoTitle from './InfoTitle';
import style from './Info.module.scss';
export default function Info() { export default function Info() {
const socket = useSocket(); const socket = useSocket();
+5 -2
View File
@@ -1,11 +1,14 @@
import React from 'react'; import React from 'react';
import { Box } from '@chakra-ui/layout'; import { Box } from '@chakra-ui/layout';
import { FiArrowUpRight } from '@react-icons/all-files/fi/FiArrowUpRight'; import { FiArrowUpRight } from '@react-icons/all-files/fi/FiArrowUpRight';
import ErrorBoundary from '../../common/components/errorBoundary/ErrorBoundary'; import ErrorBoundary from '../../common/components/errorBoundary/ErrorBoundary';
import Info from './Info';
import style from '../editors/Editor.module.scss';
import { handleLinks } from '../../common/utils/linkUtils'; import { handleLinks } from '../../common/utils/linkUtils';
import Info from './Info';
import style from '../editors/Editor.module.scss';
export default function InfoExport() { export default function InfoExport() {
return ( return (
<Box className={style.info}> <Box className={style.info}>
+3 -1
View File
@@ -1,6 +1,8 @@
import React, { useCallback, useContext, useEffect, useState } from 'react'; import React, { useCallback, useContext, useEffect, useState } from 'react';
import CollapseBar from '../../common/components/collapseBar/CollapseBar';
import { LoggingContext } from '../../app/context/LoggingContext'; import { LoggingContext } from '../../app/context/LoggingContext';
import CollapseBar from '../../common/components/collapseBar/CollapseBar';
import style from './InfoLogger.module.scss'; import style from './InfoLogger.module.scss';
export default function InfoLogger() { export default function InfoLogger() {
+2
View File
@@ -2,8 +2,10 @@ import React, { useState } from 'react';
import { APP_TABLE } from 'app/api/apiConstants'; import { APP_TABLE } from 'app/api/apiConstants';
import { getInfo, ontimePlaceholderInfo } from 'app/api/ontimeApi'; import { getInfo, ontimePlaceholderInfo } from 'app/api/ontimeApi';
import { useFetch } from 'app/hooks/useFetch'; import { useFetch } from 'app/hooks/useFetch';
import CollapseBar from '../../common/components/collapseBar/CollapseBar'; import CollapseBar from '../../common/components/collapseBar/CollapseBar';
import { openLink } from '../../common/utils/linkUtils'; import { openLink } from '../../common/utils/linkUtils';
import style from './Info.module.scss'; import style from './Info.module.scss';
export default function InfoNif() { export default function InfoNif() {
+2
View File
@@ -1,6 +1,8 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import CollapseBar from '../../common/components/collapseBar/CollapseBar'; import CollapseBar from '../../common/components/collapseBar/CollapseBar';
import style from './Info.module.scss'; import style from './Info.module.scss';
export default function InfoTitle(props) { export default function InfoTitle(props) {
@@ -1,7 +1,8 @@
import React from 'react'; import React from 'react';
import { QueryClient, QueryClientProvider } from 'react-query';
import { render, screen } from '@testing-library/react'; import { render, screen } from '@testing-library/react';
import SocketProvider from 'app/context/socketContext'; import SocketProvider from 'app/context/socketContext';
import { QueryClient, QueryClientProvider } from 'react-query';
import Info from '../Info'; import Info from '../Info';
const queryClient = new QueryClient(); const queryClient = new QueryClient();
+8 -5
View File
@@ -1,14 +1,17 @@
import React, { memo, useCallback, useContext } from 'react'; import React, { memo, useCallback, useContext } from 'react';
import { ButtonGroup, HStack } from '@chakra-ui/react'; import { ButtonGroup, HStack } from '@chakra-ui/react';
import { CursorContext } from '../../app/context/CursorContext';
import { FiChevronsUp } from '@react-icons/all-files/fi/FiChevronsUp';
import { FiChevronsDown } from '@react-icons/all-files/fi/FiChevronsDown'; import { FiChevronsDown } from '@react-icons/all-files/fi/FiChevronsDown';
import { FiChevronsUp } from '@react-icons/all-files/fi/FiChevronsUp';
import { FiTarget } from '@react-icons/all-files/fi/FiTarget'; import { FiTarget } from '@react-icons/all-files/fi/FiTarget';
import { IoCaretUp } from '@react-icons/all-files/io5/IoCaretUp';
import { IoCaretDown } from '@react-icons/all-files/io5/IoCaretDown'; import { IoCaretDown } from '@react-icons/all-files/io5/IoCaretDown';
import TooltipActionBtn from '../../common/components/buttons/TooltipActionBtn'; import { IoCaretUp } from '@react-icons/all-files/io5/IoCaretUp';
import MenuActionButtons from './MenuActionButtons';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { CursorContext } from '../../app/context/CursorContext';
import TooltipActionBtn from '../../common/components/buttons/TooltipActionBtn';
import MenuActionButtons from './MenuActionButtons';
import style from './EventListMenu.module.css'; import style from './EventListMenu.module.css';
const EventListMenu = ({ eventsHandler }) => { const EventListMenu = ({ eventsHandler }) => {
@@ -1,12 +1,12 @@
import React from 'react'; import React from 'react';
import { Menu, MenuButton, MenuItem, MenuList } from '@chakra-ui/menu';
import { IconButton } from '@chakra-ui/button'; import { IconButton } from '@chakra-ui/button';
import { Divider } from '@chakra-ui/layout';
import { Menu, MenuButton, MenuItem, MenuList } from '@chakra-ui/menu';
import { Tooltip } from '@chakra-ui/tooltip';
import { FiClock } from '@react-icons/all-files/fi/FiClock'; import { FiClock } from '@react-icons/all-files/fi/FiClock';
import { FiMinusCircle } from '@react-icons/all-files/fi/FiMinusCircle'; import { FiMinusCircle } from '@react-icons/all-files/fi/FiMinusCircle';
import { FiPlus } from '@react-icons/all-files/fi/FiPlus'; import { FiPlus } from '@react-icons/all-files/fi/FiPlus';
import { FiTrash2 } from '@react-icons/all-files/fi/FiTrash2'; import { FiTrash2 } from '@react-icons/all-files/fi/FiTrash2';
import { Divider } from '@chakra-ui/layout';
import { Tooltip } from '@chakra-ui/tooltip';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
export default function MenuActionButtons(props) { export default function MenuActionButtons(props) {
+8 -6
View File
@@ -1,18 +1,20 @@
import React, { useCallback, useContext, useEffect, useRef } from 'react'; import React, { useCallback, useContext, useEffect, useRef } from 'react';
import { useMutation, useQueryClient } from 'react-query'; import { useMutation, useQueryClient } from 'react-query';
import { VStack } from '@chakra-ui/react'; import { VStack } from '@chakra-ui/react';
import { downloadEvents, uploadEvents } from 'app/api/ontimeApi'; import { FiDownload } from '@react-icons/all-files/fi/FiDownload';
import { FiHelpCircle } from '@react-icons/all-files/fi/FiHelpCircle';
import { FiMaximize } from '@react-icons/all-files/fi/FiMaximize'; import { FiMaximize } from '@react-icons/all-files/fi/FiMaximize';
import { FiMinimize } from '@react-icons/all-files/fi/FiMinimize'; import { FiMinimize } from '@react-icons/all-files/fi/FiMinimize';
import { FiHelpCircle } from '@react-icons/all-files/fi/FiHelpCircle';
import { FiSettings } from '@react-icons/all-files/fi/FiSettings'; import { FiSettings } from '@react-icons/all-files/fi/FiSettings';
import { FiUpload } from '@react-icons/all-files/fi/FiUpload'; import { FiUpload } from '@react-icons/all-files/fi/FiUpload';
import { FiDownload } from '@react-icons/all-files/fi/FiDownload';
import { EVENTS_TABLE } from 'app/api/apiConstants'; import { EVENTS_TABLE } from 'app/api/apiConstants';
import { LoggingContext } from '../../app/context/LoggingContext'; import { downloadEvents, uploadEvents } from 'app/api/ontimeApi';
import TooltipActionBtn from '../../common/components/buttons/TooltipActionBtn';
import QuitIconBtn from '../../common/components/buttons/QuitIconBtn';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { LoggingContext } from '../../app/context/LoggingContext';
import QuitIconBtn from '../../common/components/buttons/QuitIconBtn';
import TooltipActionBtn from '../../common/components/buttons/TooltipActionBtn';
import style from './MenuBar.module.scss'; import style from './MenuBar.module.scss';
export default function MenuBar(props) { export default function MenuBar(props) {
@@ -1,8 +1,9 @@
import React from 'react'; import React from 'react';
import { render, screen } from '@testing-library/react';
import MenuBar from '../MenuBar';
import { queryClientMock } from '../../../__mocks__/QueryClient.mock';
import { QueryClientProvider } from 'react-query'; import { QueryClientProvider } from 'react-query';
import { render, screen } from '@testing-library/react';
import { queryClientMock } from '../../../__mocks__/QueryClient.mock';
import MenuBar from '../MenuBar';
const onOpenHandler = jest.fn(); const onOpenHandler = jest.fn();
const onCloseHandler = jest.fn(); const onCloseHandler = jest.fn();
@@ -1,5 +1,6 @@
import React from 'react'; import React from 'react';
import { render, screen } from '@testing-library/react'; import { render, screen } from '@testing-library/react';
import MenuActionButtons from "../MenuActionButtons"; import MenuActionButtons from "../MenuActionButtons";
const actionHandler = jest.fn(); const actionHandler = jest.fn();
@@ -1,8 +1,9 @@
import React from 'react'; import React from 'react';
import { render, screen } from '@testing-library/react';
import MenuBar from '../MenuBar';
import { queryClientMock } from '../../../__mocks__/QueryClient.mock';
import { QueryClientProvider } from 'react-query'; import { QueryClientProvider } from 'react-query';
import { render, screen } from '@testing-library/react';
import { queryClientMock } from '../../../__mocks__/QueryClient.mock';
import MenuBar from '../MenuBar';
const onOpenHandler = jest.fn(); const onOpenHandler = jest.fn();
const onCloseHandler = jest.fn(); const onCloseHandler = jest.fn();
+9 -6
View File
@@ -1,20 +1,23 @@
/* eslint-disable jsx-a11y/anchor-has-content */ /* eslint-disable jsx-a11y/anchor-has-content */
import React, { useCallback, useContext, useEffect, useState } from 'react'; import React, { useCallback, useContext, useEffect, useState } from 'react';
import { Button, IconButton } from '@chakra-ui/button'; import { Button, IconButton } from '@chakra-ui/button';
import { ModalBody } from '@chakra-ui/modal';
import { Input } from '@chakra-ui/react';
import { Tooltip } from '@chakra-ui/tooltip';
import { IoInformationCircleOutline } from '@react-icons/all-files/io5/IoInformationCircleOutline'; import { IoInformationCircleOutline } from '@react-icons/all-files/io5/IoInformationCircleOutline';
import { IoRemove } from '@react-icons/all-files/io5/IoRemove'; import { IoRemove } from '@react-icons/all-files/io5/IoRemove';
import { IoSunny } from '@react-icons/all-files/io5/IoSunny'; import { IoSunny } from '@react-icons/all-files/io5/IoSunny';
import { ModalBody } from '@chakra-ui/modal';
import { Tooltip } from '@chakra-ui/tooltip';
import { Input } from '@chakra-ui/react';
import { getAliases, postAliases } from '../../app/api/ontimeApi';
import { useFetch } from 'app/hooks/useFetch';
import { ALIASES } from 'app/api/apiConstants'; import { ALIASES } from 'app/api/apiConstants';
import { useFetch } from 'app/hooks/useFetch';
import { getAliases, postAliases } from '../../app/api/ontimeApi';
import { viewerLocations } from '../../app/appConstants'; import { viewerLocations } from '../../app/appConstants';
import { LoggingContext } from '../../app/context/LoggingContext'; import { LoggingContext } from '../../app/context/LoggingContext';
import { validateAlias } from '../../app/utils/aliases'; import { validateAlias } from '../../app/utils/aliases';
import SubmitContainer from './SubmitContainer';
import { handleLinks, host } from '../../common/utils/linkUtils'; import { handleLinks, host } from '../../common/utils/linkUtils';
import SubmitContainer from './SubmitContainer';
import style from './Modals.module.scss'; import style from './Modals.module.scss';
export default function AliasesModal() { export default function AliasesModal() {
@@ -1,18 +1,21 @@
import React, { useCallback, useContext, useEffect, useState } from 'react'; import React, { useCallback, useContext, useEffect, useState } from 'react';
import { IconButton } from '@chakra-ui/button';
import { ModalBody } from '@chakra-ui/modal'; import { ModalBody } from '@chakra-ui/modal';
import { Checkbox, FormControl, FormLabel, Input, PinInput, PinInputField } from '@chakra-ui/react'; import { Checkbox, FormControl, FormLabel, Input, PinInput, PinInputField } from '@chakra-ui/react';
import { getSettings, ontimePlaceholderSettings, postSettings } from 'app/api/ontimeApi';
import { useFetch } from 'app/hooks/useFetch';
import { APP_SETTINGS } from 'app/api/apiConstants';
import style from './Modals.module.scss';
import { LoggingContext } from '../../app/context/LoggingContext';
import { IconButton } from '@chakra-ui/button';
import { FiEye } from '@react-icons/all-files/fi/FiEye'; import { FiEye } from '@react-icons/all-files/fi/FiEye';
import { FiX } from '@react-icons/all-files/fi/FiX'; import { FiX } from '@react-icons/all-files/fi/FiX';
import SubmitContainer from './SubmitContainer'; import { APP_SETTINGS } from 'app/api/apiConstants';
import { inputProps } from './modalHelper'; import { getSettings, ontimePlaceholderSettings, postSettings } from 'app/api/ontimeApi';
import { useFetch } from 'app/hooks/useFetch';
import { LocalEventSettingsContext } from '../../app/context/LocalEventSettingsContext'; import { LocalEventSettingsContext } from '../../app/context/LocalEventSettingsContext';
import { LoggingContext } from '../../app/context/LoggingContext';
import TooltipActionBtn from '../../common/components/buttons/TooltipActionBtn'; import TooltipActionBtn from '../../common/components/buttons/TooltipActionBtn';
import { inputProps } from './modalHelper';
import SubmitContainer from './SubmitContainer';
import style from './Modals.module.scss';
const version = require('../../../package.json').version const version = require('../../../package.json').version
export default function AppSettingsModal() { export default function AppSettingsModal() {
@@ -1,13 +1,16 @@
import React, { useCallback, useEffect, useState } from 'react'; import React, { useCallback, useEffect, useState } from 'react';
import { ModalBody } from '@chakra-ui/modal'; import { ModalBody } from '@chakra-ui/modal';
import { FormLabel, Input, Textarea } from '@chakra-ui/react'; import { FormLabel, Input, Textarea } from '@chakra-ui/react';
import { EVENT_TABLE } from 'app/api/apiConstants';
import { fetchEvent, postEvent } from 'app/api/eventApi'; import { fetchEvent, postEvent } from 'app/api/eventApi';
import { useFetch } from 'app/hooks/useFetch'; import { useFetch } from 'app/hooks/useFetch';
import { EVENT_TABLE } from 'app/api/apiConstants';
import style from './Modals.module.scss';
import { eventPlaceholderSettings } from '../../app/api/ontimeApi'; import { eventPlaceholderSettings } from '../../app/api/ontimeApi';
import SubmitContainer from './SubmitContainer';
import { inputProps } from './modalHelper'; import { inputProps } from './modalHelper';
import SubmitContainer from './SubmitContainer';
import style from './Modals.module.scss';
export default function SettingsModal() { export default function SettingsModal() {
const { data, status, refetch } = useFetch(EVENT_TABLE, fetchEvent); const { data, status, refetch } = useFetch(EVENT_TABLE, fetchEvent);
@@ -1,14 +1,17 @@
import React, { useCallback, useContext, useEffect, useState } from 'react'; import React, { useCallback, useContext, useEffect, useState } from 'react';
import { ModalBody } from '@chakra-ui/modal'; import { ModalBody } from '@chakra-ui/modal';
import { FormControl, FormLabel, Input, Switch } from '@chakra-ui/react'; import { FormControl, FormLabel, Input, Switch } from '@chakra-ui/react';
import { FiInfo } from '@react-icons/all-files/fi/FiInfo';
import { APP_TABLE } from 'app/api/apiConstants';
import { getInfo, httpPlaceholder, ontimeVars, postInfo } from 'app/api/ontimeApi'; import { getInfo, httpPlaceholder, ontimeVars, postInfo } from 'app/api/ontimeApi';
import { useFetch } from 'app/hooks/useFetch'; import { useFetch } from 'app/hooks/useFetch';
import { APP_TABLE } from 'app/api/apiConstants';
import style from './Modals.module.scss';
import { LoggingContext } from '../../app/context/LoggingContext'; import { LoggingContext } from '../../app/context/LoggingContext';
import { FiInfo } from '@react-icons/all-files/fi/FiInfo';
import SubmitContainer from './SubmitContainer';
import { inputProps } from './modalHelper'; import { inputProps } from './modalHelper';
import SubmitContainer from './SubmitContainer';
import style from './Modals.module.scss';
export default function IntegrationSettingsModal() { export default function IntegrationSettingsModal() {
const { data, status, refetch } = useFetch(APP_TABLE, getInfo); const { data, status, refetch } = useFetch(APP_TABLE, getInfo);
+5 -4
View File
@@ -1,5 +1,4 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types';
import { import {
Modal, Modal,
ModalCloseButton, ModalCloseButton,
@@ -8,12 +7,14 @@ import {
ModalOverlay, ModalOverlay,
} from '@chakra-ui/modal'; } from '@chakra-ui/modal';
import { Tab, TabList, TabPanel, TabPanels, Tabs } from '@chakra-ui/tabs'; import { Tab, TabList, TabPanel, TabPanels, Tabs } from '@chakra-ui/tabs';
import EventSettingsModal from './EventSettingsModal'; import PropTypes from 'prop-types';
import OscSettingsModal from './OscSettingsModal';
import AliasesModal from './AliasesModal'; import AliasesModal from './AliasesModal';
import AppSettingsModal from './AppSettingsModal'; import AppSettingsModal from './AppSettingsModal';
import TableOptionsModal from './TableOptionsModal'; import EventSettingsModal from './EventSettingsModal';
import IntegrationSettingsModal from './IntegrationSettingsModal'; import IntegrationSettingsModal from './IntegrationSettingsModal';
import OscSettingsModal from './OscSettingsModal';
import TableOptionsModal from './TableOptionsModal';
export default function ModalManager(props) { export default function ModalManager(props) {
const { isOpen, onClose } = props; const { isOpen, onClose } = props;
@@ -1,16 +1,19 @@
import React, { useCallback, useContext, useEffect, useState } from 'react'; import React, { useCallback, useContext, useEffect, useState } from 'react';
import { ModalBody } from '@chakra-ui/modal'; import { ModalBody } from '@chakra-ui/modal';
import { FormControl, FormLabel, Input } from '@chakra-ui/react'; import { FormControl, FormLabel, Input } from '@chakra-ui/react';
import { IoInformationCircleOutline } from '@react-icons/all-files/io5/IoInformationCircleOutline';
import { OSC_SETTINGS } from 'app/api/apiConstants';
import { getOSC, oscPlaceholderSettings, postOSC } from 'app/api/ontimeApi'; import { getOSC, oscPlaceholderSettings, postOSC } from 'app/api/ontimeApi';
import { useFetch } from 'app/hooks/useFetch'; import { useFetch } from 'app/hooks/useFetch';
import { OSC_SETTINGS } from 'app/api/apiConstants';
import style from './Modals.module.scss';
import { LoggingContext } from '../../app/context/LoggingContext'; import { LoggingContext } from '../../app/context/LoggingContext';
import SubmitContainer from './SubmitContainer';
import { inputProps, portInputProps } from './modalHelper';
import { IoInformationCircleOutline } from '@react-icons/all-files/io5/IoInformationCircleOutline';
import EnableBtn from '../../common/components/buttons/EnableBtn'; import EnableBtn from '../../common/components/buttons/EnableBtn';
import { inputProps, portInputProps } from './modalHelper';
import SubmitContainer from './SubmitContainer';
import style from './Modals.module.scss';
// currently defined endpoints // currently defined endpoints
// temporary // temporary
const oscCycleEndpoints = [ const oscCycleEndpoints = [
@@ -1,8 +1,9 @@
import React from 'react'; import React from 'react';
import style from './Modals.module.scss';
import { Button } from '@chakra-ui/button'; import { Button } from '@chakra-ui/button';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import style from './Modals.module.scss';
export default function SubmitContainer(props) { export default function SubmitContainer(props) {
const { submitting, changed, revert, status } = props; const { submitting, changed, revert, status } = props;
@@ -1,14 +1,17 @@
import React, { useCallback, useEffect, useState } from 'react'; import React, { useCallback, useEffect, useState } from 'react';
import { ModalBody } from '@chakra-ui/modal'; import { ModalBody } from '@chakra-ui/modal';
import { Input } from '@chakra-ui/react'; import { Input } from '@chakra-ui/react';
import { getUserFields, postUserFields, userFieldsPlaceholder } from '../../app/api/ontimeApi';
import { useFetch } from 'app/hooks/useFetch';
import { USERFIELDS } from 'app/api/apiConstants';
import SubmitContainer from './SubmitContainer';
import style from './Modals.module.scss';
import { IoInformationCircleOutline } from '@react-icons/all-files/io5/IoInformationCircleOutline'; import { IoInformationCircleOutline } from '@react-icons/all-files/io5/IoInformationCircleOutline';
import { USERFIELDS } from 'app/api/apiConstants';
import { useFetch } from 'app/hooks/useFetch';
import { getUserFields, postUserFields, userFieldsPlaceholder } from '../../app/api/ontimeApi';
import { handleLinks, host } from '../../common/utils/linkUtils'; import { handleLinks, host } from '../../common/utils/linkUtils';
import SubmitContainer from './SubmitContainer';
import style from './Modals.module.scss';
export default function TableOptionsModal() { export default function TableOptionsModal() {
const { data, status, refetch } = useFetch(USERFIELDS, getUserFields); const { data, status, refetch } = useFetch(USERFIELDS, getUserFields);
const [changed, setChanged] = useState(false); const [changed, setChanged] = useState(false);
+10 -7
View File
@@ -1,8 +1,6 @@
import React, { useCallback, useContext, useEffect, useMemo } from 'react'; import React, { useCallback, useContext, useEffect, useMemo } from 'react';
import { TableSettingsContext } from '../../app/context/TableSettingsContext';
import { useBlockLayout, useColumnOrder, useResizeColumns, useTable } from 'react-table'; import { useBlockLayout, useColumnOrder, useResizeColumns, useTable } from 'react-table';
import { Tooltip } from '@chakra-ui/tooltip'; import { Tooltip } from '@chakra-ui/tooltip';
import PropTypes from 'prop-types';
import { import {
closestCenter, closestCenter,
DndContext, DndContext,
@@ -17,14 +15,19 @@ import {
SortableContext, SortableContext,
sortableKeyboardCoordinates, sortableKeyboardCoordinates,
} from '@dnd-kit/sortable'; } from '@dnd-kit/sortable';
import PropTypes from 'prop-types';
import { TableSettingsContext } from '../../app/context/TableSettingsContext';
import { useLocalStorage } from '../../app/hooks/useLocalStorage'; import { useLocalStorage } from '../../app/hooks/useLocalStorage';
import { defaultColumnOrder, defaultHiddenColumns } from './defaults';
import { makeColumns } from './columns';
import EventRow from './tableRows/EventRow';
import DelayRow from './tableRows/DelayRow';
import BlockRow from './tableRows/BlockRow';
import SortableCell from './tableElements/SortableCell'; import SortableCell from './tableElements/SortableCell';
import TableSettings from './tableElements/TableSettings'; import TableSettings from './tableElements/TableSettings';
import BlockRow from './tableRows/BlockRow';
import DelayRow from './tableRows/DelayRow';
import EventRow from './tableRows/EventRow';
import { makeColumns } from './columns';
import { defaultColumnOrder, defaultHiddenColumns } from './defaults';
import style from './Table.module.scss'; import style from './Table.module.scss';
export default function OntimeTable({ tableData, userFields, handleUpdate, selectedId }) { export default function OntimeTable({ tableData, userFields, handleUpdate, selectedId }) {
+4 -2
View File
@@ -1,7 +1,9 @@
import React from 'react'; import React from 'react';
import ProtectRoute from '../../common/components/protectRoute/ProtectRoute';
import TableWrapper from './TableWrapper';
import { TableSettingsProvider } from '../../app/context/TableSettingsContext'; import { TableSettingsProvider } from '../../app/context/TableSettingsContext';
import ProtectRoute from '../../common/components/protectRoute/ProtectRoute';
import TableWrapper from './TableWrapper';
export default function ProtectedTable() { export default function ProtectedTable() {
return ( return (
+10 -7
View File
@@ -1,16 +1,19 @@
import React, { useContext, useEffect, useState } from 'react'; import React, { useContext, useEffect, useState } from 'react';
import { useFetch } from '../../app/hooks/useFetch'; import { Tooltip } from '@chakra-ui/tooltip';
import { TableSettingsContext } from '../../app/context/TableSettingsContext'; import { FiSettings } from '@react-icons/all-files/fi/FiSettings';
import { FiTarget } from '@react-icons/all-files/fi/FiTarget';
import { IoMoon } from '@react-icons/all-files/io5/IoMoon';
import { EVENT_TABLE } from '../../app/api/apiConstants'; import { EVENT_TABLE } from '../../app/api/apiConstants';
import { fetchEvent } from '../../app/api/eventApi'; import { fetchEvent } from '../../app/api/eventApi';
import { FiSettings } from '@react-icons/all-files/fi/FiSettings';
import { IoMoon } from '@react-icons/all-files/io5/IoMoon';
import { FiTarget } from '@react-icons/all-files/fi/FiTarget';
import { useSocket } from '../../app/context/socketContext'; import { useSocket } from '../../app/context/socketContext';
import { TableSettingsContext } from '../../app/context/TableSettingsContext';
import { useFetch } from '../../app/hooks/useFetch';
import { formatDisplay } from '../../common/utils/dateConfig'; import { formatDisplay } from '../../common/utils/dateConfig';
import { Tooltip } from '@chakra-ui/tooltip';
import PlaybackIcon from './tableElements/PlaybackIcon';
import { stringFromMillis } from '../../common/utils/time'; import { stringFromMillis } from '../../common/utils/time';
import PlaybackIcon from './tableElements/PlaybackIcon';
import style from './Table.module.scss'; import style from './Table.module.scss';
export default function TableHeader() { export default function TableHeader() {
+9 -6
View File
@@ -1,13 +1,16 @@
import React, { useCallback, useContext, useEffect, useState } from 'react'; import React, { useCallback, useContext, useEffect, useState } from 'react';
import { useFetch } from '../../app/hooks/useFetch';
import { useSocket } from '../../app/context/socketContext';
import { TableSettingsContext } from '../../app/context/TableSettingsContext';
import { EVENTS_TABLE, USERFIELDS } from '../../app/api/apiConstants'; import { EVENTS_TABLE, USERFIELDS } from '../../app/api/apiConstants';
import { fetchAllEvents, requestPatch } from '../../app/api/eventsApi'; import { fetchAllEvents, requestPatch } from '../../app/api/eventsApi';
import TableHeader from './TableHeader';
import OntimeTable from './OntimeTable';
import useMutateEvents from '../../app/hooks/useMutateEvents';
import { getUserFields } from '../../app/api/ontimeApi'; import { getUserFields } from '../../app/api/ontimeApi';
import { useSocket } from '../../app/context/socketContext';
import { TableSettingsContext } from '../../app/context/TableSettingsContext';
import { useFetch } from '../../app/hooks/useFetch';
import useMutateEvents from '../../app/hooks/useMutateEvents';
import OntimeTable from './OntimeTable';
import TableHeader from './TableHeader';
import style from './Table.module.scss'; import style from './Table.module.scss';
export default function TableWrapper() { export default function TableWrapper() {

Some files were not shown because too many files have changed in this diff Show More