mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-18 21:54:09 +00:00
refactor: small fixes and style tweaks
fix: prevent reflow on editing images fix: schedule overview fix: report on all events refactor: over-under time colours fix: prevent edit on delete
This commit is contained in:
committed by
Carlos Valente
parent
1e1f547ce1
commit
ad2ef3b53f
@@ -18,8 +18,8 @@ export function getOffsetText(offset: MaybeNumber): string {
|
|||||||
return offsetText;
|
return offsetText;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getOffsetState(offset: MaybeNumber): 'ahead' | 'behind' | 'muted' | null {
|
export function getOffsetState(offset: MaybeNumber): 'over' | 'under' | 'muted' | null {
|
||||||
if (offset === null) return null;
|
if (offset === null) return null;
|
||||||
if (offset === 0) return 'muted';
|
if (offset === 0) return 'muted';
|
||||||
return offset < 0 ? 'behind' : 'ahead';
|
return offset < 0 ? 'over' : 'under';
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -1,7 +1,7 @@
|
|||||||
th.over {
|
th.over {
|
||||||
color: $ontime-delay-text;
|
color: $playback-over;
|
||||||
}
|
}
|
||||||
|
|
||||||
th.under {
|
th.under {
|
||||||
color: $playback-ahead;
|
color: $playback-under;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,8 +29,8 @@ export default function ReportSettings() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const combinedReport = useMemo(() => {
|
const combinedReport = useMemo(() => {
|
||||||
return getCombinedReport(reportData, data.entries, data.order);
|
return getCombinedReport(reportData, data.entries, data.flatOrder);
|
||||||
}, [reportData, data.entries, data.order]);
|
}, [reportData, data.entries, data.flatOrder]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Panel.Section>
|
<Panel.Section>
|
||||||
@@ -82,7 +82,7 @@ export default function ReportSettings() {
|
|||||||
return 'over';
|
return 'over';
|
||||||
})();
|
})();
|
||||||
return (
|
return (
|
||||||
<tr key={entry.index}>
|
<tr key={entry.id}>
|
||||||
<th>{entry.index}</th>
|
<th>{entry.index}</th>
|
||||||
<th>{entry.cue}</th>
|
<th>{entry.cue}</th>
|
||||||
<th>{entry.title}</th>
|
<th>{entry.title}</th>
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { makeCSVFromArrayOfArrays } from '../../../../common/utils/csv';
|
|||||||
import { formatTime } from '../../../../common/utils/time';
|
import { formatTime } from '../../../../common/utils/time';
|
||||||
|
|
||||||
export type CombinedReport = {
|
export type CombinedReport = {
|
||||||
|
id: EntryId;
|
||||||
index: number;
|
index: number;
|
||||||
title: string;
|
title: string;
|
||||||
cue: string;
|
cue: string;
|
||||||
@@ -16,24 +17,48 @@ export type CombinedReport = {
|
|||||||
/**
|
/**
|
||||||
* Creates a combined report with the rundown data
|
* Creates a combined report with the rundown data
|
||||||
*/
|
*/
|
||||||
export function getCombinedReport(report: OntimeReport, rundown: RundownEntries, order: EntryId[]): CombinedReport[] {
|
export function getCombinedReport(
|
||||||
|
report: OntimeReport,
|
||||||
|
rundown: RundownEntries,
|
||||||
|
flatOrder: EntryId[],
|
||||||
|
): CombinedReport[] {
|
||||||
if (Object.keys(report).length === 0) return [];
|
if (Object.keys(report).length === 0) return [];
|
||||||
if (order.length === 0) return [];
|
if (flatOrder.length === 0) return [];
|
||||||
|
|
||||||
const combinedReport: CombinedReport[] = [];
|
const combinedReport: CombinedReport[] = [];
|
||||||
|
|
||||||
for (const [key, value] of Object.entries(report)) {
|
let index = 1;
|
||||||
if (!rundown[key] || !isOntimeEvent(rundown[key])) continue;
|
for (let i = 0; i < flatOrder.length; i++) {
|
||||||
|
const id = flatOrder[i];
|
||||||
|
const entry = rundown[id];
|
||||||
|
if (!entry || !isOntimeEvent(entry)) continue;
|
||||||
|
|
||||||
combinedReport.push({
|
if (!(id in report)) {
|
||||||
index: order.findIndex((id) => id === key),
|
combinedReport.push({
|
||||||
title: rundown[key].title,
|
id: id,
|
||||||
cue: rundown[key].cue,
|
index: index,
|
||||||
scheduledStart: rundown[key].timeStart,
|
title: entry.title,
|
||||||
actualEnd: value.endedAt,
|
cue: entry.cue,
|
||||||
scheduledEnd: rundown[key].timeEnd,
|
scheduledStart: entry.timeStart,
|
||||||
actualStart: value.startedAt,
|
actualEnd: null,
|
||||||
});
|
scheduledEnd: entry.timeEnd,
|
||||||
|
actualStart: null,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (id in report) {
|
||||||
|
combinedReport.push({
|
||||||
|
id: id,
|
||||||
|
index: index,
|
||||||
|
title: entry.title,
|
||||||
|
cue: entry.cue,
|
||||||
|
scheduledStart: entry.timeStart,
|
||||||
|
actualEnd: report[id].endedAt,
|
||||||
|
scheduledEnd: entry.timeEnd,
|
||||||
|
actualStart: report[id].startedAt,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return combinedReport;
|
return combinedReport;
|
||||||
|
|||||||
@@ -55,18 +55,6 @@
|
|||||||
color: $muted-gray;
|
color: $muted-gray;
|
||||||
}
|
}
|
||||||
|
|
||||||
.offset {
|
|
||||||
color: $muted-gray;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ahead {
|
|
||||||
color: $playback-ahead;
|
|
||||||
}
|
|
||||||
|
|
||||||
.behind {
|
|
||||||
color: $ontime-delay-text;
|
|
||||||
}
|
|
||||||
|
|
||||||
.labelTitle {
|
.labelTitle {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|||||||
@@ -18,17 +18,18 @@ import { cx, enDash, timerPlaceholder } from '../../../common/utils/styleUtils';
|
|||||||
import { formatTime, useTimeUntilStart } from '../../../common/utils/time';
|
import { formatTime, useTimeUntilStart } from '../../../common/utils/time';
|
||||||
import { calculateEndAndDaySpan, formattedTime } from '../overview.utils';
|
import { calculateEndAndDaySpan, formattedTime } from '../overview.utils';
|
||||||
|
|
||||||
import { TimeColumn } from './TimeLayout';
|
import { OverUnder, TimeColumn } from './TimeLayout';
|
||||||
|
|
||||||
import style from './TimeElements.module.scss';
|
import style from './TimeElements.module.scss';
|
||||||
|
|
||||||
export function StartTimes() {
|
export function StartTimes() {
|
||||||
const { plannedEnd, plannedStart, actualStart, expectedEnd } = useRuntimeOverview();
|
const { plannedEnd, plannedStart, actualStart, expectedEnd } = useRuntimeOverview();
|
||||||
|
|
||||||
|
const plannedStartText = plannedStart === null ? timerPlaceholder : formatTime(plannedStart);
|
||||||
|
|
||||||
const [maybePlannedEnd, maybePlannedDaySpan] = useMemo(() => calculateEndAndDaySpan(plannedEnd), [plannedEnd]);
|
const [maybePlannedEnd, maybePlannedDaySpan] = useMemo(() => calculateEndAndDaySpan(plannedEnd), [plannedEnd]);
|
||||||
|
|
||||||
const [maybeExpectedEnd, maybeExpectedDaySpan] = useMemo(() => calculateEndAndDaySpan(expectedEnd), [expectedEnd]);
|
const [maybeExpectedEnd, maybeExpectedDaySpan] = useMemo(() => calculateEndAndDaySpan(expectedEnd), [expectedEnd]);
|
||||||
|
const plannedEndText = maybePlannedEnd === null ? timerPlaceholder : formatTime(maybePlannedEnd);
|
||||||
const muted = maybeExpectedEnd === null;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={style.column}>
|
<div className={style.column}>
|
||||||
@@ -36,31 +37,31 @@ export function StartTimes() {
|
|||||||
<span className={style.label}>Start</span>
|
<span className={style.label}>Start</span>
|
||||||
<div className={style.labelledElement}>
|
<div className={style.labelledElement}>
|
||||||
<Tooltip text='Planned start time' render={<TbCalendar className={style.icon} />} />
|
<Tooltip text='Planned start time' render={<TbCalendar className={style.icon} />} />
|
||||||
<span className={cx([style.time])}>{formatTime(plannedStart)}</span>
|
<span className={cx([style.time, plannedStart === null && style.muted])}>{plannedStartText}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className={style.labelledElement}>
|
<div className={style.labelledElement}>
|
||||||
<Tooltip text='Actual start time' render={<TbCalendarClock className={style.icon} />} />
|
<Tooltip text='Actual start time' render={<TbCalendarClock className={style.icon} />} />
|
||||||
<span className={cx([style.time, muted && style.muted])}>{formattedTime(actualStart)}</span>
|
<span className={cx([style.time, actualStart === null && style.muted])}>{formattedTime(actualStart)}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={style.row}>
|
<div className={style.row}>
|
||||||
<span className={style.label}>End</span>
|
<span className={style.label}>End</span>
|
||||||
<div className={style.labelledElement}>
|
<div className={style.labelledElement}>
|
||||||
<Tooltip text='Planned end time' render={<TbCalendar className={style.icon} />} />
|
<Tooltip text='Planned end time' render={<TbCalendar className={style.icon} />} />
|
||||||
{maybePlannedDaySpan >= 0 ? (
|
{maybePlannedDaySpan > 0 ? (
|
||||||
<Tooltip
|
<Tooltip
|
||||||
text={`Event spans over ${maybePlannedDaySpan + 1} days`}
|
text={`Event spans over ${maybePlannedDaySpan + 1} days`}
|
||||||
render={<span className={cx([style.time, style.daySpan])} />}
|
render={<span className={cx([style.time, style.daySpan])} />}
|
||||||
>
|
>
|
||||||
{formatTime(maybePlannedEnd)}
|
{plannedEndText}
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
) : (
|
) : (
|
||||||
<span className={cx([style.time, muted && style.muted])}>{formatTime(maybePlannedEnd)}</span>
|
<span className={cx([style.time, plannedEnd === null && style.muted])}>{plannedEndText}</span>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className={style.labelledElement}>
|
<div className={style.labelledElement}>
|
||||||
<Tooltip text='Expected end time' render={<TbCalendarStar className={style.icon} />} />
|
<Tooltip text='Expected end time' render={<TbCalendarStar className={style.icon} />} />
|
||||||
{maybeExpectedEnd !== null && maybeExpectedDaySpan >= 0 ? (
|
{maybeExpectedEnd !== null && maybeExpectedDaySpan > 0 ? (
|
||||||
<Tooltip
|
<Tooltip
|
||||||
text={`Event spans over ${maybeExpectedDaySpan + 1} days`}
|
text={`Event spans over ${maybeExpectedDaySpan + 1} days`}
|
||||||
render={<span className={cx([style.time, style.daySpan])} />}
|
render={<span className={cx([style.time, style.daySpan])} />}
|
||||||
@@ -68,7 +69,9 @@ export function StartTimes() {
|
|||||||
{formattedTime(maybeExpectedEnd)}
|
{formattedTime(maybeExpectedEnd)}
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
) : (
|
) : (
|
||||||
<span className={cx([style.time, muted && style.muted])}>{formattedTime(maybeExpectedEnd)}</span>
|
<span className={cx([style.time, maybeExpectedEnd === null && style.muted])}>
|
||||||
|
{formattedTime(maybeExpectedEnd)}
|
||||||
|
</span>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -199,11 +202,10 @@ export function OffsetOverview() {
|
|||||||
|
|
||||||
const isPlaying = isPlaybackActive(playback);
|
const isPlaying = isPlaybackActive(playback);
|
||||||
const correctedOffset = offset * -1;
|
const correctedOffset = offset * -1;
|
||||||
const offsetState = getOffsetState(correctedOffset);
|
const offsetState = getOffsetState(offset);
|
||||||
const offsetClasses = cx([style.offset, offsetState && style[offsetState]]);
|
|
||||||
const offsetText = getOffsetText(isPlaying ? correctedOffset : null);
|
const offsetText = getOffsetText(isPlaying ? correctedOffset : null);
|
||||||
|
|
||||||
return <TimeColumn label='Over / under' value={offsetText} className={offsetClasses} testId='offset' />;
|
return <OverUnder state={offsetState} value={offsetText} testId='offset' />;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ClockOverview() {
|
export function ClockOverview() {
|
||||||
|
|||||||
@@ -22,34 +22,31 @@
|
|||||||
.label {
|
.label {
|
||||||
line-height: 0.9em;
|
line-height: 0.9em;
|
||||||
width: 7em;
|
width: 7em;
|
||||||
}
|
display: flex;
|
||||||
}
|
gap: 0.25rem;
|
||||||
|
|
||||||
.row {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 0.5rem;
|
|
||||||
height: 2.25em;
|
|
||||||
|
|
||||||
.label {
|
|
||||||
text-align: right;
|
|
||||||
width: 5em;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.clock {
|
&[data-state="over"] {
|
||||||
font-size: 1.25rem;
|
.label .over {
|
||||||
|
color: $playback-over;
|
||||||
|
}
|
||||||
|
.clock {
|
||||||
|
color: $playback-over;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&[data-state="under"] {
|
||||||
|
.label .under {
|
||||||
|
color: $playback-under;
|
||||||
|
}
|
||||||
|
.clock {
|
||||||
|
color: $playback-under;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&[data-state="muted"] {
|
||||||
|
.clock {
|
||||||
|
color: $muted-gray;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.daySpan {
|
|
||||||
&::after {
|
|
||||||
content: "*";
|
|
||||||
vertical-align: super;
|
|
||||||
font-size: 0.75em;
|
|
||||||
color: $info-blue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.muted {
|
|
||||||
color: $muted-gray;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,6 +1,3 @@
|
|||||||
import { PropsWithChildren } from 'react';
|
|
||||||
|
|
||||||
import Tooltip from '../../../common/components/tooltip/Tooltip';
|
|
||||||
import { cx } from '../../../common/utils/styleUtils';
|
import { cx } from '../../../common/utils/styleUtils';
|
||||||
|
|
||||||
import style from './TimeLayout.module.scss';
|
import style from './TimeLayout.module.scss';
|
||||||
@@ -25,40 +22,23 @@ export function TimeColumn({ label, value, muted, className, testId }: TimeLayou
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function TimeRow({ label, value, daySpan, muted, className }: TimeLayoutProps) {
|
interface OverUnderProps {
|
||||||
return (
|
state: 'over' | 'under' | 'muted' | null;
|
||||||
<div className={style.row}>
|
value: string;
|
||||||
<span className={style.label}>{label}</span>
|
testId: string;
|
||||||
{daySpan ? (
|
|
||||||
<Tooltip
|
|
||||||
text={`Event spans over ${daySpan + 1} days`}
|
|
||||||
render={<span />}
|
|
||||||
className={cx([style.clock, style.daySpan, className])}
|
|
||||||
>
|
|
||||||
{value}
|
|
||||||
</Tooltip>
|
|
||||||
) : (
|
|
||||||
<span className={cx([style.clock, muted && style.muted, className])}>{value}</span>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function TimeElementsRow({ label, value, daySpan, muted, className }: PropsWithChildren<TimeLayoutProps>) {
|
export function OverUnder({ state, value, testId }: OverUnderProps) {
|
||||||
return (
|
return (
|
||||||
<div className={style.row}>
|
<div className={style.column} data-state={state}>
|
||||||
<span className={style.label}>{label}</span>
|
<div className={style.label}>
|
||||||
{daySpan ? (
|
<span className={style.over}>Over</span>
|
||||||
<Tooltip
|
<span>/</span>
|
||||||
text={`Event spans over ${daySpan + 1} days`}
|
<span className={style.under}>Under</span>
|
||||||
render={<span />}
|
</div>
|
||||||
className={cx([style.clock, style.daySpan, className])}
|
<span className={style.clock} data-testid={testId}>
|
||||||
>
|
{value}
|
||||||
{value}
|
</span>
|
||||||
</Tooltip>
|
|
||||||
) : (
|
|
||||||
<span className={cx([style.clock, muted && style.muted, className])}>{value}</span>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import NullableTimeInput from '../../../common/components/input/time-input/Nulla
|
|||||||
import AppLink from '../../../common/components/link/app-link/AppLink';
|
import AppLink from '../../../common/components/link/app-link/AppLink';
|
||||||
import { useEntryActions } from '../../../common/hooks/useEntryAction';
|
import { useEntryActions } from '../../../common/hooks/useEntryAction';
|
||||||
import useCustomFields from '../../../common/hooks-query/useCustomFields';
|
import useCustomFields from '../../../common/hooks-query/useCustomFields';
|
||||||
|
import { getOffsetState } from '../../../common/utils/offset';
|
||||||
import { enDash, timerPlaceholder } from '../../../common/utils/styleUtils';
|
import { enDash, timerPlaceholder } from '../../../common/utils/styleUtils';
|
||||||
import TextLikeInput from '../../../views/cuesheet/cuesheet-table/cuesheet-table-elements/TextLikeInput';
|
import TextLikeInput from '../../../views/cuesheet/cuesheet-table/cuesheet-table-elements/TextLikeInput';
|
||||||
|
|
||||||
@@ -54,7 +55,7 @@ export default function BlockEditor({ block }: BlockEditorProps) {
|
|||||||
|
|
||||||
const isEditor = window.location.pathname.includes('editor');
|
const isEditor = window.location.pathname.includes('editor');
|
||||||
const planOffset = typeof block.targetDuration !== 'number' ? null : block.duration - block.targetDuration;
|
const planOffset = typeof block.targetDuration !== 'number' ? null : block.duration - block.targetDuration;
|
||||||
const planOffsetLabel = planOffset !== null && planOffset > 0 ? 'behind' : 'ahead';
|
const planOffsetLabel = planOffset !== null ? getOffsetState(planOffset * -1) : null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={style.content}>
|
<div className={style.content}>
|
||||||
|
|||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
.imageContainer {
|
.imageContainer {
|
||||||
width: 100%;
|
width: 75px;
|
||||||
height: 100%;
|
height: 75px;
|
||||||
background-color: $gray-1250;
|
background-color: $gray-1250;
|
||||||
display: grid;
|
display: grid;
|
||||||
place-content: center;
|
place-content: center;
|
||||||
|
|||||||
+2
-2
@@ -6,11 +6,11 @@
|
|||||||
justify-self: end;
|
justify-self: end;
|
||||||
|
|
||||||
&.over {
|
&.over {
|
||||||
color: $ontime-delay-text;
|
color: $playback-over;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.under {
|
&.under {
|
||||||
color: $playback-ahead;
|
color: $playback-under;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.due {
|
&.due {
|
||||||
|
|||||||
@@ -59,7 +59,8 @@ export default function RundownMilestone({ colour, cue, entryId, hasCursor, titl
|
|||||||
updateEntry({ id: entryId, [field]: value });
|
updateEntry({ id: entryId, [field]: value });
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDelete = () => {
|
const handleDelete = (event: MouseEvent) => {
|
||||||
|
event.stopPropagation();
|
||||||
deleteEntry([entryId]);
|
deleteEntry([entryId]);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,9 @@ $playback-ahead: $green-500;
|
|||||||
$active-indicator: #8bb33d;
|
$active-indicator: #8bb33d;
|
||||||
$text-black: $gray-1350;
|
$text-black: $gray-1350;
|
||||||
|
|
||||||
|
$playback-over: #F57C13;
|
||||||
|
$playback-under: $green-500;
|
||||||
|
|
||||||
// interface panels
|
// interface panels
|
||||||
$bg-container-l1: $gray-1350;
|
$bg-container-l1: $gray-1350;
|
||||||
$bg-container-l2: $gray-1300;
|
$bg-container-l2: $gray-1300;
|
||||||
|
|||||||
@@ -50,12 +50,12 @@ $indeterminate-width: clamp(32px, 3vw, 48px);
|
|||||||
color: $ontime-delay-text;
|
color: $ontime-delay-text;
|
||||||
}
|
}
|
||||||
|
|
||||||
&--ahead {
|
&--over {
|
||||||
color: $green-500;
|
color: $playback-over;
|
||||||
}
|
}
|
||||||
|
|
||||||
&--behind {
|
&--under {
|
||||||
color: $orange-500;
|
color: $playback-under;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { useRuntimeOffset } from '../../../common/hooks/useSocket';
|
import { useRuntimeOffset } from '../../../common/hooks/useSocket';
|
||||||
|
import { getOffsetState } from '../../../common/utils/offset';
|
||||||
import { cx } from '../../../common/utils/styleUtils';
|
import { cx } from '../../../common/utils/styleUtils';
|
||||||
import { formatTime } from '../../../common/utils/time';
|
import { formatTime } from '../../../common/utils/time';
|
||||||
import SuperscriptTime from '../../../features/viewers/common/superscript-time/SuperscriptTime';
|
import SuperscriptTime from '../../../features/viewers/common/superscript-time/SuperscriptTime';
|
||||||
@@ -121,11 +122,7 @@ function ProjectedTime(props: OffsetTimeProps) {
|
|||||||
|
|
||||||
const projectedOffset = offset - delay;
|
const projectedOffset = offset - delay;
|
||||||
const projectedTime = formatTime(time - offset, formatOptions);
|
const projectedTime = formatTime(time - offset, formatOptions);
|
||||||
|
const projectedState = getOffsetState(projectedOffset);
|
||||||
|
|
||||||
return (
|
return <SuperscriptTime className={`entry-times--${projectedState}`} time={projectedTime} />;
|
||||||
<SuperscriptTime
|
|
||||||
className={cx([projectedOffset > 0 && 'entry-times--ahead', projectedOffset < 0 && 'entry-times--behind'])}
|
|
||||||
time={projectedTime}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -141,12 +141,12 @@ $item-height: 3.5rem;
|
|||||||
color: $delay-color;
|
color: $delay-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sub__schedule--ahead {
|
.sub__schedule--over {
|
||||||
color: $green-500;
|
color: $playback-over
|
||||||
}
|
}
|
||||||
|
|
||||||
.sub__schedule--behind {
|
.sub__schedule--under {
|
||||||
color: $orange-500;
|
color: $playback-under
|
||||||
}
|
}
|
||||||
|
|
||||||
.sub__title {
|
.sub__title {
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { useFadeOutOnInactivity } from '../../common/hooks/useFadeOutOnInactivit
|
|||||||
import useFollowComponent from '../../common/hooks/useFollowComponent';
|
import useFollowComponent from '../../common/hooks/useFollowComponent';
|
||||||
import { useCurrentDay, useRuntimeOffset } from '../../common/hooks/useSocket';
|
import { useCurrentDay, useRuntimeOffset } from '../../common/hooks/useSocket';
|
||||||
import { ViewExtendedTimer } from '../../common/models/TimeManager.type';
|
import { ViewExtendedTimer } from '../../common/models/TimeManager.type';
|
||||||
|
import { getOffsetState } from '../../common/utils/offset';
|
||||||
import { cx } from '../../common/utils/styleUtils';
|
import { cx } from '../../common/utils/styleUtils';
|
||||||
import { throttle } from '../../common/utils/throttle';
|
import { throttle } from '../../common/utils/throttle';
|
||||||
import FollowButton from '../../features/operator/follow-button/FollowButton';
|
import FollowButton from '../../features/operator/follow-button/FollowButton';
|
||||||
@@ -134,14 +135,13 @@ function ProjectedSchedule(props: ProjectedScheduleProps) {
|
|||||||
|
|
||||||
// offset is negative if we are ahead
|
// offset is negative if we are ahead
|
||||||
const projectedOffset = offset - delay;
|
const projectedOffset = offset - delay;
|
||||||
|
const projectState = getOffsetState(projectedOffset);
|
||||||
const classes = cx([projectedOffset > 0 && 'sub__schedule--ahead', projectedOffset < 0 && 'sub__schedule--behind']);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<ClockTime
|
<ClockTime
|
||||||
value={timeStart - projectedOffset}
|
value={timeStart - projectedOffset}
|
||||||
className={classes}
|
className={`sub__schedule--${projectState}`}
|
||||||
preferredFormat12='h:mm'
|
preferredFormat12='h:mm'
|
||||||
preferredFormat24='HH:mm'
|
preferredFormat24='HH:mm'
|
||||||
/>
|
/>
|
||||||
|
|||||||
+1
-1
@@ -103,7 +103,7 @@ function DurationInput({
|
|||||||
onClick={handleFakeFocus}
|
onClick={handleFakeFocus}
|
||||||
onFocus={handleFakeFocus}
|
onFocus={handleFakeFocus}
|
||||||
muted={!lockedValue}
|
muted={!lockedValue}
|
||||||
offset={delayed ? 'behind' : undefined}
|
offset={delayed ? 'over' : undefined}
|
||||||
ref={textRef}
|
ref={textRef}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
|
|||||||
+4
-4
@@ -14,12 +14,12 @@
|
|||||||
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
&.ahead {
|
&.under {
|
||||||
color: $playback-ahead;
|
color: $playback-under;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.behind {
|
&.over {
|
||||||
color: $ontime-delay-text;
|
color: $playback-over;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.muted {
|
&.muted {
|
||||||
|
|||||||
+1
-1
@@ -5,7 +5,7 @@ import { cx } from '../../../../common/utils/styleUtils';
|
|||||||
import style from './TextLikeInput.module.scss';
|
import style from './TextLikeInput.module.scss';
|
||||||
|
|
||||||
interface TextLikeInputProps extends HTMLAttributes<HTMLSpanElement> {
|
interface TextLikeInputProps extends HTMLAttributes<HTMLSpanElement> {
|
||||||
offset?: 'ahead' | 'behind';
|
offset?: 'over' | 'under' | 'muted' | null;
|
||||||
muted?: boolean;
|
muted?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ function TimeInputDuration({
|
|||||||
onClick={handleFakeFocus}
|
onClick={handleFakeFocus}
|
||||||
onFocus={handleFakeFocus}
|
onFocus={handleFakeFocus}
|
||||||
muted={!lockedValue}
|
muted={!lockedValue}
|
||||||
offset={delayed ? 'behind' : undefined}
|
offset={delayed ? 'over' : undefined}
|
||||||
ref={textRef}
|
ref={textRef}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
|
|||||||
@@ -63,12 +63,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.ahead {
|
.over {
|
||||||
color: $playback-ahead;
|
color: $playback-over;
|
||||||
}
|
}
|
||||||
|
|
||||||
.behind {
|
.under {
|
||||||
color: $ontime-delay-text;
|
color: $playback-under;
|
||||||
}
|
}
|
||||||
|
|
||||||
.muted {
|
.muted {
|
||||||
|
|||||||
Reference in New Issue
Block a user