Feat/table (#105)

* feat/table add react-table
* feat/table add protected table route
* feat/table upgrade dependencies
* feat/table support parsing of new properties

Co-authored-by: DeepSource Bot <bot@deepsource.io>
This commit is contained in:
Carlos Valente
2022-04-09 22:05:56 +02:00
committed by GitHub
parent 8841a02754
commit 67ddcd8c68
146 changed files with 7423 additions and 5780 deletions
@@ -1,13 +1,14 @@
import React from 'react';
import { IconButton } from '@chakra-ui/button';
import { Tooltip } from '@chakra-ui/tooltip';
import { FiCheck } from '@react-icons/all-files/fi/FiCheck';
export default function ApplyIconBtn(props) {
const { clickhandler, ...rest } = props;
const { clickhandler, size, ...rest } = props;
return (
<Tooltip label='Apply delays'>
<IconButton
size={props.size || 'xs'}
size={size || 'xs'}
icon={<FiCheck />}
colorScheme='orange'
onClick={clickhandler}
@@ -1,13 +1,14 @@
import React from 'react';
import { IconButton } from '@chakra-ui/button';
import { Tooltip } from '@chakra-ui/tooltip';
import { FiChevronsUp } from '@react-icons/all-files/fi/FiChevronsUp';
export default function CollapseBtn(props) {
const { clickhandler } = props;
const { clickhandler, size } = props;
return (
<Tooltip label='Collapse all'>
<IconButton
size={props.size || 'xs'}
size={size || 'xs'}
icon={<FiChevronsUp />}
colorScheme='white'
variant='outline'
@@ -1,14 +1,15 @@
import React from 'react';
import { IconButton } from '@chakra-ui/button';
import { Tooltip } from '@chakra-ui/tooltip';
import { IoCaretDown } from '@react-icons/all-files/io5/IoCaretDown';
export default function CursorDownBtn(props) {
const { clickhandler, active, ref } = props;
const { clickhandler, active, ref, size } = props;
return (
<Tooltip label='Move cursor down Alt + ↓'>
<IconButton
ref={ref}
size={props.size || 'xs'}
size={size || 'xs'}
icon={<IoCaretDown />}
color={active ? 'pink.100' : 'pink.300'}
borderColor={active ? undefined : 'pink.300'}
@@ -1,14 +1,15 @@
import React from 'react';
import { IconButton } from '@chakra-ui/button';
import { Tooltip } from '@chakra-ui/tooltip';
import { FiTarget } from '@react-icons/all-files/fi/FiTarget';
export default function CursorLockedBtn(props) {
const { clickhandler, active, ref } = props;
const { clickhandler, active, ref, size } = props;
return (
<Tooltip label='Lock cursor to current'>
<IconButton
<IconButton
ref={ref}
size={props.size || 'xs'}
size={size || 'xs'}
icon={<FiTarget />}
color={active ? 'pink.100' : 'pink.300'}
borderColor={active ? undefined : 'pink.300'}
@@ -1,14 +1,15 @@
import React from 'react';
import { IconButton } from '@chakra-ui/button';
import { Tooltip } from '@chakra-ui/tooltip';
import { IoCaretUp } from '@react-icons/all-files/io5/IoCaretUp';
export default function CursorUpBtn(props) {
const { clickhandler, active, ref } = props;
const { clickhandler, active, ref, size } = props;
return (
<Tooltip label='Move cursor up Alt + ↑'>
<IconButton
ref={ref}
size={props.size || 'xs'}
size={size || 'xs'}
icon={<IoCaretUp />}
color={active ? 'pink.100' : 'pink.300'}
borderColor={active ? undefined : 'pink.300'}
@@ -1,10 +1,11 @@
import React from 'react';
import { IconButton } from '@chakra-ui/button';
import { useState } from 'react';
import { IoRemove } from '@react-icons/all-files/io5/IoRemove';
import { Tooltip } from '@chakra-ui/tooltip';
export default function DeleteIconBtn(props) {
const { actionHandler, ...rest } = props;
const { actionHandler, size, ...rest } = props;
const [loading, setLoading] = useState(false);
const handleClick = () => {
@@ -15,7 +16,7 @@ export default function DeleteIconBtn(props) {
return (
<Tooltip label='Delete'>
<IconButton
size={props.size || 'xs'}
size={size || 'xs'}
icon={<IoRemove />}
colorScheme='red'
onClick={handleClick}
@@ -1,12 +1,13 @@
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';
export default function EnableBtn(props) {
const { active, text, actionHandler } = props;
const { active, text, actionHandler, size } = props;
return (
<Button
size={props.size || 'xs'}
size={size || 'xs'}
leftIcon={active ? <IoCheckmarkSharp /> : <IoCloseSharp />}
colorScheme='blue'
variant={active ? 'solid' : 'outline'}
@@ -1,13 +1,14 @@
import React from 'react';
import { IconButton } from '@chakra-ui/button';
import { Tooltip } from '@chakra-ui/tooltip';
import { FiChevronsDown } from '@react-icons/all-files/fi/FiChevronsDown';
export default function ExpandBtn(props) {
const { clickhandler } = props;
const { clickhandler, size } = props;
return (
<Tooltip label='Expand all'>
<IconButton
size={props.size || 'xs'}
size={size || 'xs'}
icon={<FiChevronsDown />}
colorScheme='white'
variant='outline'
@@ -1,11 +1,12 @@
import React from 'react';
import { IconButton } from '@chakra-ui/button';
import { IoPlaySkipForward } from '@react-icons/all-files/io5/IoPlaySkipForward';
import { Tooltip } from '@chakra-ui/tooltip';
export default function NextIconBtn(props) {
const { clickhandler, ...rest } = props;
const { clickhandler, disabled, ...rest } = props;
return (
<Tooltip label='Next event' openDelay={500} shouldWrapChildren={props.disabled}>
<Tooltip label='Next event' openDelay={500} shouldWrapChildren={disabled}>
<IconButton
icon={<IoPlaySkipForward size='22px' />}
colorScheme='whiteAlpha'
@@ -1,14 +1,15 @@
import React from 'react';
import { IconButton } from '@chakra-ui/button';
import { IoMicSharp } from '@react-icons/all-files/io5/IoMicSharp';
import { IoMicOffOutline } from '@react-icons/all-files/io5/IoMicOffOutline';
import { Tooltip } from '@chakra-ui/tooltip';
export default function OnAirIconBtn(props) {
const { actionHandler, active, ...rest } = props;
const { actionHandler, active, size, ...rest } = props;
return (
<Tooltip label={active ? 'Go Off Air' : 'Go On Air'} openDelay={500}>
<IconButton
size={props.size || 'xs'}
size={size || 'xs'}
icon={active ? <IoMicSharp size='24px' /> : <IoMicOffOutline size='24px' />}
colorScheme='blue'
variant={active ? 'solid' : 'outline'}
@@ -1,11 +1,12 @@
import React from 'react';
import { IconButton } from '@chakra-ui/button';
import { IoPause } from '@react-icons/all-files/io5/IoPause';
import { Tooltip } from '@chakra-ui/tooltip';
export default function PauseIconBtn(props) {
const { clickhandler, active, ...rest } = props;
const { clickhandler, active, disabled, ...rest } = props;
return (
<Tooltip label='Pause timer' openDelay={500} shouldWrapChildren={props.disabled}>
<Tooltip label='Pause timer' openDelay={500} shouldWrapChildren={disabled}>
<IconButton
icon={<IoPause size='24px' />}
colorScheme='orange'
@@ -1,11 +1,12 @@
import React from 'react';
import { IconButton } from '@chakra-ui/button';
import { IoPlaySkipBack } from '@react-icons/all-files/io5/IoPlaySkipBack';
import { Tooltip } from '@chakra-ui/tooltip';
export default function PrevIconBtn(props) {
const { clickhandler, ...rest } = props;
const { clickhandler, disabled, ...rest } = props;
return (
<Tooltip label='Previous event' openDelay={500} shouldWrapChildren={props.disabled}>
<Tooltip label='Previous event' openDelay={500} shouldWrapChildren={disabled}>
<IconButton
icon={<IoPlaySkipBack size='22px' />}
colorScheme='whiteAlpha'
@@ -1,19 +1,18 @@
import React from 'react';
import { IconButton } from '@chakra-ui/button';
import { Tooltip } from '@chakra-ui/tooltip';
import { FiUsers } from '@react-icons/all-files/fi/FiUsers';
export default function PublicIconBtn(props) {
const { actionHandler, active, ...rest } = props;
const { actionHandler, active, size, ...rest } = props;
return (
<Tooltip label={active ? 'Make event private' : 'Make event public'}>
<IconButton
size={props.size || 'xs'}
size={size || 'xs'}
icon={<FiUsers />}
colorScheme='blue'
variant={active ? 'solid' : 'outline'}
onClick={() =>
actionHandler('update', { field: 'isPublic', value: !active })
}
onClick={() => actionHandler('update', { field: 'isPublic', value: !active })}
_focus={{ boxShadow: 'none' }}
{...rest}
/>
@@ -1,11 +1,12 @@
import React from 'react';
import { IconButton } from '@chakra-ui/button';
import { IoArrowUndo } from '@react-icons/all-files/io5/IoArrowUndo';
import { Tooltip } from '@chakra-ui/tooltip';
export default function ReloadIconButton(props) {
const { clickhandler, ...rest } = props;
const { clickhandler, disabled, ...rest } = props;
return (
<Tooltip label='Reload event' openDelay={500} shouldWrapChildren={props.disabled}>
<Tooltip label='Reload event' openDelay={500} shouldWrapChildren={disabled}>
<IconButton
icon={<IoArrowUndo size='22px' />}
colorScheme='whiteAlpha'
@@ -1,11 +1,12 @@
import React from 'react';
import { IconButton } from '@chakra-ui/button';
import { IoTimeOutline } from '@react-icons/all-files/io5/IoTimeOutline';
import { Tooltip } from '@chakra-ui/tooltip';
export default function RollIconBtn(props) {
const { clickhandler, active, ...rest } = props;
const { clickhandler, active, disabled, ...rest } = props;
return (
<Tooltip label='Roll mode' openDelay={500} shouldWrapChildren={props.disabled}>
<Tooltip label='Roll mode' openDelay={500} shouldWrapChildren={disabled}>
<IconButton
icon={<IoTimeOutline size='24px' />}
colorScheme='blue'
@@ -1,11 +1,12 @@
import React from 'react';
import { IconButton } from '@chakra-ui/button';
import { IoPlay } from '@react-icons/all-files/io5/IoPlay';
import { Tooltip } from '@chakra-ui/tooltip';
export default function StartIconBtn(props) {
const { clickhandler, active, ...rest } = props;
const { clickhandler, active, disabled, ...rest } = props;
return (
<Tooltip label='Start timer' openDelay={500} shouldWrapChildren={props.disabled}>
<Tooltip label='Start timer' openDelay={500} shouldWrapChildren={disabled}>
<IconButton
icon={<IoPlay size='24px' />}
colorScheme='green'
@@ -1,11 +1,12 @@
import React from 'react';
import { IconButton } from '@chakra-ui/button';
import { IoStop } from '@react-icons/all-files/io5/IoStop';
import { Tooltip } from '@chakra-ui/tooltip';
export default function UnloadIconBtn(props) {
const { clickhandler, ...rest } = props;
const { clickhandler, disabled, ...rest } = props;
return (
<Tooltip label='Unload event' openDelay={500} shouldWrapChildren={props.disabled}>
<Tooltip label='Unload event' openDelay={500} shouldWrapChildren={disabled}>
<IconButton
icon={<IoStop size='22px' />}
colorScheme='red'
@@ -1,14 +1,15 @@
import React from 'react';
import { IconButton } from '@chakra-ui/button';
import { IoSunny } from '@react-icons/all-files/io5/IoSunny';
import { Tooltip } from '@chakra-ui/tooltip';
export default function VisibleIconBtn(props) {
const { actionHandler, active, ...rest } = props;
const { actionHandler, active, size, ...rest } = props;
return (
<Tooltip label={active ? 'Make invisible' : 'Make visible'} openDelay={500}>
<IconButton
size={props.size || 'xs'}
icon={<IoSunny size={'18px'}/>}
size={size || 'xs'}
icon={<IoSunny size='18px' />}
colorScheme='blue'
variant={active ? 'solid' : 'outline'}
onClick={() =>
@@ -1,3 +1,4 @@
import React from 'react';
import PropTypes from "prop-types";
import style from "../../../features/info/Info.module.scss";
import {Icon} from "@chakra-ui/react";
@@ -1,4 +1,4 @@
import { memo } from 'react';
import React, { memo } from 'react';
import { formatDisplay } from 'common/utils/dateConfig';
import PropTypes from 'prop-types';
import styles from './Countdown.module.css';
@@ -28,5 +28,5 @@ Countdown.propTypes = {
time: PropTypes.number,
small: PropTypes.bool,
isNegative: PropTypes.bool,
hideZeroHour: PropTypes.bool,
hideZeroHours: PropTypes.bool,
};
@@ -1,3 +1,4 @@
/* eslint-disable react/destructuring-assignment */
import React from 'react';
import { LoggingContext } from '../../../app/context/LoggingContext';
@@ -1,5 +1,5 @@
import React, { useContext } from 'react';
import EditableTimer from 'common/input/EditableTimer';
import { useContext } from 'react';
import { LoggingContext } from '../../../app/context/LoggingContext';
import { validateTimes } from '../../../app/entryValidator';
import PropTypes from 'prop-types';
@@ -8,6 +8,13 @@ export default function EventTimes(props) {
const { actionHandler, delay, timeStart, timeEnd, previousEnd } = props;
const { emitWarning } = useContext(LoggingContext);
/**
* This code is duplicated from EventTimesVertical
* @description Validates a time input against its pair
* @param {string} entry - field to validate: timeStart, timeEnd, durationOverride
* @param {number} val - field value
* @return {boolean}
*/
const handleValidate = (entry, val) => {
if (val == null || timeStart == null || timeEnd == null) return true;
if (timeStart === 0) return true;
@@ -18,8 +25,10 @@ export default function EventTimes(props) {
start = val;
} else if (entry === 'timeEnd') {
end = val;
} else if (entry === 'durationOverride'){
return true;
} else {
return;
return false
}
const valid = validateTimes(start, end);
@@ -54,8 +63,8 @@ export default function EventTimes(props) {
EventTimes.propTypes = {
actionHandler: PropTypes.func.isRequired,
delay: PropTypes.number.isRequired,
timeStart: PropTypes.number.isRequired,
timeEnd: PropTypes.number.isRequired,
previousEnd: PropTypes.number.isRequired,
delay: PropTypes.number,
timeStart: PropTypes.number,
timeEnd: PropTypes.number,
previousEnd: PropTypes.number,
};
@@ -1,6 +1,6 @@
import React, { useContext } from 'react';
import EditableTimer from 'common/input/EditableTimer';
import { stringFromMillis } from 'ontime-utils/time';
import { useContext } from 'react';
import { LoggingContext } from '../../../app/context/LoggingContext';
import { validateTimes } from '../../../app/entryValidator';
import PropTypes from 'prop-types';
@@ -56,11 +56,11 @@ const TimesDelayed = (props) => {
TimesDelayed.propTypes = {
handleValidate: PropTypes.func.isRequired,
actionHandler: PropTypes.func.isRequired,
delay: PropTypes.number.isRequired,
timeStart: PropTypes.number.isRequired,
timeEnd: PropTypes.number.isRequired,
duration: PropTypes.number.isRequired,
previousEnd: PropTypes.number.isRequired,
delay: PropTypes.number,
timeStart: PropTypes.number,
timeEnd: PropTypes.number,
duration: PropTypes.number,
previousEnd: PropTypes.number,
};
const Times = (props) => {
@@ -102,16 +102,23 @@ const Times = (props) => {
Times.propTypes = {
handleValidate: PropTypes.func.isRequired,
actionHandler: PropTypes.func.isRequired,
timeStart: PropTypes.number.isRequired,
timeEnd: PropTypes.number.isRequired,
duration: PropTypes.number.isRequired,
previousEnd: PropTypes.number.isRequired,
timeStart: PropTypes.number,
timeEnd: PropTypes.number,
duration: PropTypes.number,
previousEnd: PropTypes.number,
};
export default function EventTimesVertical(props) {
const { delay, timeStart, timeEnd, duration, previousEnd } = props;
const { delay, timeStart, timeEnd, duration, previousEnd, actionHandler } = props;
const { emitWarning } = useContext(LoggingContext);
/**
* This code is duplicated from EventTimes
* @description Validates a time input against its pair
* @param {string} entry - field to validate: timeStart, timeEnd, durationOverride
* @param {number} val - field value
* @return {boolean}
*/
const handleValidate = (entry, val) => {
if (val == null || timeStart == null || timeEnd == null) return true;
if (timeStart === 0) return true;
@@ -122,8 +129,10 @@ export default function EventTimesVertical(props) {
start = val;
} else if (entry === 'timeEnd') {
end = val;
} else if (entry === 'durationOverride') {
return true;
} else {
return;
return false;
}
const valid = validateTimes(start, end);
@@ -137,7 +146,7 @@ export default function EventTimesVertical(props) {
return delay != null && delay !== 0 ? (
<TimesDelayed
handleValidate={handleValidate}
actionHandler={props.actionHandler}
actionHandler={actionHandler}
delay={delay}
timeStart={timeStart}
timeEnd={timeEnd}
@@ -147,7 +156,7 @@ export default function EventTimesVertical(props) {
) : (
<Times
handleValidate={handleValidate}
actionHandler={props.actionHandler}
actionHandler={actionHandler}
timeStart={timeStart}
timeEnd={timeEnd}
duration={duration}
@@ -157,9 +166,10 @@ export default function EventTimesVertical(props) {
}
EventTimesVertical.propTypes = {
delay: PropTypes.number.isRequired,
timeStart: PropTypes.number.isRequired,
timeEnd: PropTypes.number.isRequired,
duration: PropTypes.number.isRequired,
previousEnd: PropTypes.number.isRequired,
};
delay: PropTypes.number,
timeStart: PropTypes.number,
timeEnd: PropTypes.number,
duration: PropTypes.number,
previousEnd: PropTypes.number,
actionHandler: PropTypes.func.isRequired,
};
@@ -1,3 +1,4 @@
import React from 'react';
import { clamp } from 'app/utils/math';
import styles from './MyProgressBar.module.css';
+1 -1
View File
@@ -1,8 +1,8 @@
import React, { useState, useEffect, useCallback } from 'react';
import PropTypes from "prop-types";
import { Link } from 'react-router-dom';
import { Image } from '@chakra-ui/react';
import { AnimatePresence, motion } from 'framer-motion';
import { useState, useEffect, useCallback } from 'react';
import navlogo from 'assets/images/logos/LOGO-72.png';
import style from './NavLogo.module.scss';
@@ -1,14 +1,14 @@
import React, { useContext, useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import style from './ProtectRoute.module.scss';
import { PinInput, PinInputField } from '@chakra-ui/react';
import { IconButton } from '@chakra-ui/button';
import { FiCheck } from '@react-icons/all-files/fi/FiCheck';
import { AppContext } from '../../../app/context/AppContext';
import { useContext, useEffect, useState } from 'react';
export default function ProtectRoute(props) {
const isLocal = window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1';
export default function ProtectRoute({ children }) {
const isLocal =
window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1';
const [pin, setPin] = useState('');
const [failed, setFailed] = useState(false);
const { auth, validate } = useContext(AppContext);
@@ -23,7 +23,7 @@ export default function ProtectRoute(props) {
if (!r) {
setFailed(true);
}
}
};
return (
<>
@@ -56,12 +56,12 @@ export default function ProtectRoute(props) {
</div>
</div>
) : (
props.children
children
)}
</>
);
}
ProtectRoute.propTypes = {
children: PropTypes.node.isRequired
children: PropTypes.node.isRequired,
};
@@ -1,12 +1,13 @@
import React, { useEffect, useState } from 'react';
import TodayItem from './TodayItem';
import style from './Paginator.module.css';
import { useEffect, useState } from 'react';
import { useInterval } from 'app/hooks/useInterval';
import PropTypes from 'prop-types';
export default function Paginator(props) {
const { events, selectedId } = props;
const LIMIT_PER_PAGE = props.limit || 8;
const SCROLL_TIME = props.time * 1000 || 10000;
const { events, selectedId, limit = 7, time = 10, isBackstage } = props;
const LIMIT_PER_PAGE = limit;
const SCROLL_TIME = time * 1000 || 10000;
const [numEvents, setNumEvents] = useState(0);
const [page, setPage] = useState([]);
const [pages, setPages] = useState(0);
@@ -46,10 +47,7 @@ export default function Paginator(props) {
<div className={style.nav}>
{pages > 1 &&
[...Array(pages)].map((p, i) => (
<div
key={i}
className={i === selPage ? style.navItemSelected : style.navItem}
/>
<div key={i} className={i === selPage ? style.navItemSelected : style.navItem} />
))}
</div>
<div className={style.entries}>
@@ -63,6 +61,7 @@ export default function Paginator(props) {
timeStart={e.timeStart}
timeEnd={e.timeEnd}
title={e.title}
colour={isBackstage ? e.colour : ''}
backstageEvent={!e.isPublic}
/>
);
@@ -71,3 +70,11 @@ export default function Paginator(props) {
</>
);
}
Paginator.propTypes = {
events: PropTypes.array,
selectedId: PropTypes.string,
limit: PropTypes.number,
time: PropTypes.number,
isBackstage: PropTypes.bool,
};
@@ -1,3 +1,4 @@
import React from 'react';
import style from './TitleCard.module.css';
export default function TitleCard(props) {
@@ -1,3 +1,4 @@
import React from 'react';
import style from './TitleSide.module.css';
export default function TitleSide(props) {
@@ -1,25 +1,38 @@
import React from 'react';
import { stringFromMillis } from 'ontime-utils/time';
import style from './Paginator.module.css';
import PropTypes from 'prop-types';
export default function TodayItem(props) {
const { selected, timeStart, timeEnd, title, backstageEvent } = props;
const { selected, timeStart, timeEnd, title, backstageEvent, colour } = props;
// Format timers
const start = stringFromMillis(timeStart, false) || '';
const end = stringFromMillis(timeEnd, false) || '';
// user colours
const userColour = colour !== '' ? colour : 'transparent';
// select styling
let selectStyle = style.entryPast;
if (selected === 1) selectStyle = style.entryNow;
else if (selected === 2) selectStyle = style.entryFuture;
return (
<div className={selectStyle}>
<div
className={`${style.entryTimes} ${
backstageEvent ? style.backstage : undefined
}`}
>{`${start} · ${end}`}</div>
<div className={selectStyle} style={{ borderLeft: `4px solid ${userColour}` }}>
<div className={`${style.entryTimes} ${backstageEvent ? style.backstage : undefined}`}>
{`${start} · ${end}`}
</div>
<div className={style.entryTitle}>{title}</div>
{backstageEvent && <div className={style.backstageInd}/>}
{backstageEvent && <div className={style.backstageInd} />}
</div>
);
}
TodayItem.propTypes = {
selected: PropTypes.bool,
timeStart: PropTypes.number,
timeEnd: PropTypes.number,
title: PropTypes.string,
backstageEvent: PropTypes.bool,
colour: PropTypes.string,
};