mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-19 06:04:05 +00:00
refactor: improve section style and composition
This commit is contained in:
committed by
Carlos Valente
parent
2f2c26ed00
commit
6199d0ad10
@@ -8,7 +8,7 @@
|
||||
color: $ui-white;
|
||||
transition-property: color;
|
||||
transition-duration: $transition-time-action;
|
||||
border-radius: 99px;
|
||||
border-radius: $component-border-radius-full;
|
||||
|
||||
// similar styles to ontime-button-subtle
|
||||
background-color: $gray-1050;
|
||||
@@ -27,13 +27,16 @@
|
||||
|
||||
.title {
|
||||
font-size: 1rem;
|
||||
color: $ui-white;
|
||||
color: $title-gray;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.label {
|
||||
display: block;
|
||||
font-size: calc(1rem - 3px);
|
||||
font-size: $aux-text-size;
|
||||
color: $label-gray;
|
||||
margin-bottom: 0.25rem;
|
||||
margin-bottom: $element-inner-spacing;
|
||||
max-width: max-content; // prevent label from taking entire row
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { LabelHTMLAttributes, ReactNode } from 'react';
|
||||
import type { HTMLAttributes, LabelHTMLAttributes } from 'react';
|
||||
import { IoArrowUp } from '@react-icons/all-files/io5/IoArrowUp';
|
||||
import { type IconBaseProps } from '@react-icons/all-files/lib';
|
||||
|
||||
@@ -10,8 +10,13 @@ export function Corner({ className, ...elementProps }: IconBaseProps) {
|
||||
return <IoArrowUp className={cx([style.corner, className])} {...elementProps} />;
|
||||
}
|
||||
|
||||
export function Title({ children }: { children: ReactNode }) {
|
||||
return <h3 className={style.title}>{children}</h3>;
|
||||
export function Title({ children, className, ...elementProps }: HTMLAttributes<HTMLHeadingElement>) {
|
||||
const classes = cx([style.title, className]);
|
||||
return (
|
||||
<h3 className={classes} {...elementProps}>
|
||||
{children}
|
||||
</h3>
|
||||
);
|
||||
}
|
||||
|
||||
export function Label({ children, className, ...elementProps }: LabelHTMLAttributes<HTMLLabelElement>) {
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
.side {
|
||||
max-height: 100%;
|
||||
max-width: 45rem;
|
||||
margin: 2rem 0;
|
||||
margin: 0.5rem 0;
|
||||
padding: 1rem;
|
||||
padding-right: 0;
|
||||
background-color: $gray-1325;
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
.eventEditor {
|
||||
color: $label-gray;
|
||||
max-height: 100%;
|
||||
overflow-y: auto;
|
||||
padding: 0.5rem;
|
||||
padding-inline: 0.5rem;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -16,7 +15,7 @@
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
gap: 1.5rem;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
@@ -30,19 +29,22 @@
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
margin-top: 0.5rem;
|
||||
|
||||
h3 {
|
||||
margin-bottom: -0.5rem; // bring the title closer to the section elements
|
||||
}
|
||||
}
|
||||
|
||||
.decorated {
|
||||
color: var(--decorator-color, $ui-white);
|
||||
background-color: var(--decorator-bg, $gray-1100);
|
||||
width: fit-content;
|
||||
padding: 0 0.5rem;
|
||||
border-radius: 2px;
|
||||
padding-inline: 0.5rem;
|
||||
border-radius: $component-border-radius-sm;
|
||||
}
|
||||
|
||||
.delayLabel {
|
||||
font-size: calc(1rem - 3px);
|
||||
font-size: $aux-text-size;
|
||||
color: $ontime-delay-text;
|
||||
|
||||
&::after {
|
||||
@@ -56,7 +58,8 @@
|
||||
gap: 0.5rem;
|
||||
max-width: max-content;
|
||||
cursor: pointer;
|
||||
height: 30px; // manually match the height of a text input
|
||||
height: 2rem; // manually match the height of a text input
|
||||
margin-bottom: 0; // reset margin from label component
|
||||
}
|
||||
|
||||
.inline {
|
||||
@@ -68,6 +71,13 @@
|
||||
.splitTwo {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
column-gap: 1.5rem;
|
||||
column-gap: 1rem;
|
||||
row-gap: 1rem;
|
||||
}
|
||||
|
||||
.tooltipIcon {
|
||||
color: $blue-500;
|
||||
display: inline-block;
|
||||
font-size: 1.25em;
|
||||
margin-left: 0.25em;
|
||||
}
|
||||
|
||||
@@ -79,14 +79,14 @@ export default function EventEditor(props: EventEditorProps) {
|
||||
handleSubmit={handleSubmit}
|
||||
/>
|
||||
<div className={style.column}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
|
||||
<Editor.Title>Custom Fields</Editor.Title>
|
||||
<Editor.Title>
|
||||
Custom Fields
|
||||
{isEditor && (
|
||||
<Button variant='ontime-subtle' size='sm' onClick={handleOpenCustomManager}>
|
||||
Manage
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</Editor.Title>
|
||||
{Object.keys(customFields).map((fieldKey) => {
|
||||
const key = `${event.id}-${fieldKey}`;
|
||||
const fieldName = `custom-${fieldKey}`;
|
||||
|
||||
@@ -38,8 +38,6 @@
|
||||
}
|
||||
|
||||
.prompt {
|
||||
font-size: 1rem;
|
||||
text-align: left;
|
||||
margin-left: 4rem;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { memo } from 'react';
|
||||
import { memo, PropsWithChildren } from 'react';
|
||||
import { Kbd } from '@chakra-ui/react';
|
||||
|
||||
import { deviceAlt, deviceMod } from '../../../common/utils/deviceUtils';
|
||||
import * as Editor from '../../editors/editor-utils/EditorUtils';
|
||||
|
||||
import style from './EventEditorEmpty.module.scss';
|
||||
|
||||
@@ -11,7 +12,7 @@ function EventEditorEmpty() {
|
||||
return (
|
||||
<div className={style.eventEditor} data-testid='editor-container'>
|
||||
<div className={style.shortcutSection}>
|
||||
<div className={style.prompt}>Rundown shortcuts:</div>
|
||||
<Editor.Title className={style.prompt}>Rundown shortcuts</Editor.Title>
|
||||
<table className={style.shortcuts}>
|
||||
<tbody>
|
||||
<tr>
|
||||
@@ -168,6 +169,6 @@ function EventEditorEmpty() {
|
||||
);
|
||||
}
|
||||
|
||||
function AuxKey({ children }: { children: React.ReactNode }) {
|
||||
function AuxKey({ children }: PropsWithChildren) {
|
||||
return <span className={style.divider}>{children}</span>;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { memo } from 'react';
|
||||
import { Select, Switch } from '@chakra-ui/react';
|
||||
import { Select, Switch, Tooltip } from '@chakra-ui/react';
|
||||
import { IoInformationCircle } from '@react-icons/all-files/io5/IoInformationCircle';
|
||||
import { EndAction, MaybeString, TimerType, TimeStrategy } from 'ontime-types';
|
||||
import { millisToString, parseUserTime } from 'ontime-utils';
|
||||
|
||||
@@ -80,8 +81,8 @@ function EventEditorTimes(props: EventEditorTimesProps) {
|
||||
return (
|
||||
<>
|
||||
<div className={style.column}>
|
||||
<Editor.Title>Event schedule</Editor.Title>
|
||||
<div>
|
||||
<Editor.Label>Event schedule</Editor.Label>
|
||||
<div className={style.inline}>
|
||||
<TimeInputFlow
|
||||
eventId={eventId}
|
||||
@@ -92,11 +93,15 @@ function EventEditorTimes(props: EventEditorTimesProps) {
|
||||
linkStart={linkStart}
|
||||
delay={delay}
|
||||
countToEnd={countToEnd}
|
||||
showLabels
|
||||
/>
|
||||
</div>
|
||||
<div className={style.delayLabel}>{delayLabel}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={style.column}>
|
||||
<Editor.Title>Event Behaviour</Editor.Title>
|
||||
<div className={style.splitTwo}>
|
||||
<div>
|
||||
<Editor.Label htmlFor='endAction'>End Action</Editor.Label>
|
||||
@@ -129,7 +134,16 @@ function EventEditorTimes(props: EventEditorTimesProps) {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={style.column}>
|
||||
<Editor.Title>
|
||||
<Tooltip label='Changes how the timer is displayed in different views. It is not reflected in the rundown'>
|
||||
<span>
|
||||
Display Options
|
||||
<IoInformationCircle className={style.tooltipIcon} />
|
||||
</span>
|
||||
</Tooltip>
|
||||
</Editor.Title>
|
||||
<div className={style.splitTwo}>
|
||||
<div>
|
||||
<Editor.Label htmlFor='timerType'>Timer Type</Editor.Label>
|
||||
|
||||
@@ -29,6 +29,7 @@ const EventEditorTitles = (props: EventEditorTitlesProps) => {
|
||||
|
||||
return (
|
||||
<div className={style.column}>
|
||||
<Editor.Title>Event Data</Editor.Title>
|
||||
<div className={style.splitTwo}>
|
||||
<div>
|
||||
<Editor.Label htmlFor='eventId'>Event ID (read only)</Editor.Label>
|
||||
|
||||
@@ -11,6 +11,7 @@ import TimeInputWithButton from '../../../common/components/input/time-input/Tim
|
||||
import { useEventAction } from '../../../common/hooks/useEventAction';
|
||||
import { cx } from '../../../common/utils/styleUtils';
|
||||
import { tooltipDelayFast, tooltipDelayMid } from '../../../ontimeConfig';
|
||||
import * as Editor from '../../editors/editor-utils/EditorUtils';
|
||||
|
||||
import style from './TimeInputFlow.module.scss';
|
||||
|
||||
@@ -23,10 +24,11 @@ interface EventBlockTimerProps {
|
||||
timeStrategy: TimeStrategy;
|
||||
linkStart: MaybeString;
|
||||
delay: number;
|
||||
showLabels?: boolean;
|
||||
}
|
||||
|
||||
function TimeInputFlow(props: EventBlockTimerProps) {
|
||||
const { eventId, countToEnd, timeStart, timeEnd, duration, timeStrategy, linkStart, delay } = props;
|
||||
const { eventId, countToEnd, timeStart, timeEnd, duration, timeStrategy, linkStart, delay, showLabels } = props;
|
||||
const { updateEvent, updateTimer } = useEventAction();
|
||||
|
||||
// In sync with EventEditorTimes
|
||||
@@ -62,60 +64,69 @@ function TimeInputFlow(props: EventBlockTimerProps) {
|
||||
|
||||
return (
|
||||
<>
|
||||
<TimeInputWithButton<TimeField>
|
||||
name='timeStart'
|
||||
submitHandler={handleSubmit}
|
||||
time={timeStart}
|
||||
hasDelay={hasDelay}
|
||||
placeholder='Start'
|
||||
disabled={Boolean(linkStart)}
|
||||
>
|
||||
<Tooltip label='Link start to previous end' openDelay={tooltipDelayMid}>
|
||||
<InputRightElement className={activeStart} onClick={() => handleLink(!linkStart)}>
|
||||
<span className={style.timeLabel}>S</span>
|
||||
<span className={style.fourtyfive}>{linkStart ? <IoLink /> : <IoUnlink />}</span>
|
||||
</InputRightElement>
|
||||
</Tooltip>
|
||||
</TimeInputWithButton>
|
||||
<div>
|
||||
{showLabels && <Editor.Label className={style.sectionTitle}>Start time</Editor.Label>}
|
||||
<TimeInputWithButton<TimeField>
|
||||
name='timeStart'
|
||||
submitHandler={handleSubmit}
|
||||
time={timeStart}
|
||||
hasDelay={hasDelay}
|
||||
placeholder='Start'
|
||||
disabled={Boolean(linkStart)}
|
||||
>
|
||||
<Tooltip label='Link start to previous end' openDelay={tooltipDelayMid}>
|
||||
<InputRightElement className={activeStart} onClick={() => handleLink(!linkStart)}>
|
||||
<span className={style.timeLabel}>S</span>
|
||||
<span className={style.fourtyfive}>{linkStart ? <IoLink /> : <IoUnlink />}</span>
|
||||
</InputRightElement>
|
||||
</Tooltip>
|
||||
</TimeInputWithButton>
|
||||
</div>
|
||||
|
||||
<TimeInputWithButton<TimeField>
|
||||
name='timeEnd'
|
||||
submitHandler={handleSubmit}
|
||||
time={timeEnd}
|
||||
hasDelay={hasDelay}
|
||||
disabled={isLockedDuration}
|
||||
placeholder='End'
|
||||
>
|
||||
<Tooltip label='Lock end' openDelay={tooltipDelayMid}>
|
||||
<InputRightElement
|
||||
className={activeEnd}
|
||||
onClick={() => handleChangeStrategy(TimeStrategy.LockEnd)}
|
||||
data-testid='lock__end'
|
||||
>
|
||||
<span className={style.timeLabel}>E</span>
|
||||
{isLockedEnd ? <IoLockClosed /> : <IoLockOpenOutline />}
|
||||
</InputRightElement>
|
||||
</Tooltip>
|
||||
</TimeInputWithButton>
|
||||
<div>
|
||||
{showLabels && <Editor.Label>End time</Editor.Label>}
|
||||
<TimeInputWithButton<TimeField>
|
||||
name='timeEnd'
|
||||
submitHandler={handleSubmit}
|
||||
time={timeEnd}
|
||||
hasDelay={hasDelay}
|
||||
disabled={isLockedDuration}
|
||||
placeholder='End'
|
||||
>
|
||||
<Tooltip label='Lock end' openDelay={tooltipDelayMid}>
|
||||
<InputRightElement
|
||||
className={activeEnd}
|
||||
onClick={() => handleChangeStrategy(TimeStrategy.LockEnd)}
|
||||
data-testid='lock__end'
|
||||
>
|
||||
<span className={style.timeLabel}>E</span>
|
||||
{isLockedEnd ? <IoLockClosed /> : <IoLockOpenOutline />}
|
||||
</InputRightElement>
|
||||
</Tooltip>
|
||||
</TimeInputWithButton>
|
||||
</div>
|
||||
|
||||
<TimeInputWithButton<TimeField>
|
||||
name='duration'
|
||||
submitHandler={handleSubmit}
|
||||
time={duration}
|
||||
disabled={isLockedEnd}
|
||||
placeholder='Duration'
|
||||
>
|
||||
<Tooltip label='Lock duration' openDelay={tooltipDelayMid}>
|
||||
<InputRightElement
|
||||
className={activeDuration}
|
||||
onClick={() => handleChangeStrategy(TimeStrategy.LockDuration)}
|
||||
data-testid='lock__duration'
|
||||
>
|
||||
<span className={style.timeLabel}>D</span>
|
||||
{isLockedDuration ? <IoLockClosed /> : <IoLockOpenOutline />}
|
||||
</InputRightElement>
|
||||
</Tooltip>
|
||||
</TimeInputWithButton>
|
||||
<div>
|
||||
{showLabels && <Editor.Label>Duration</Editor.Label>}
|
||||
<TimeInputWithButton<TimeField>
|
||||
name='duration'
|
||||
submitHandler={handleSubmit}
|
||||
time={duration}
|
||||
disabled={isLockedEnd}
|
||||
placeholder='Duration'
|
||||
>
|
||||
<Tooltip label='Lock duration' openDelay={tooltipDelayMid}>
|
||||
<InputRightElement
|
||||
className={activeDuration}
|
||||
onClick={() => handleChangeStrategy(TimeStrategy.LockDuration)}
|
||||
data-testid='lock__duration'
|
||||
>
|
||||
<span className={style.timeLabel}>D</span>
|
||||
{isLockedDuration ? <IoLockClosed /> : <IoLockOpenOutline />}
|
||||
</InputRightElement>
|
||||
</Tooltip>
|
||||
</TimeInputWithButton>
|
||||
</div>
|
||||
|
||||
{warnings.length > 0 && (
|
||||
<div className={style.timerNote}>
|
||||
|
||||
Reference in New Issue
Block a user