mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-11 02:13:48 +00:00
2a890cf2b3
* fix: issue where a count-to-end would lead to incorrect expected times * fix: include add time in overtime when countToEnd * fix: ui and server use same calculation for expected end
84 lines
3.3 KiB
TypeScript
84 lines
3.3 KiB
TypeScript
import { getExpectedEnd, getExpectedStart } from 'ontime-utils';
|
||
import { IoPencil } from 'react-icons/io5';
|
||
|
||
import Button from '../../common/components/buttons/Button';
|
||
import useReport from '../../common/hooks-query/useReport';
|
||
import { useFadeOutOnInactivity } from '../../common/hooks/useFadeOutOnInactivity';
|
||
import { useExpectedStartData } from '../../common/hooks/useSocket';
|
||
import { cx } from '../../common/utils/styleUtils';
|
||
import SuperscriptTime from '../common/superscript-time/SuperscriptTime';
|
||
import { getPropertyValue } from '../common/viewUtils';
|
||
import { useCountdownOptions } from './countdown.options';
|
||
import { CountdownEvent, CountdownTarget, useSubscriptionDisplayData } from './countdown.utils';
|
||
import { ScheduleTime } from './CountdownSubscriptions';
|
||
|
||
import './SingleEventCountdown.scss';
|
||
|
||
interface SingleEventCountdownProps {
|
||
subscribedEvent: CountdownTarget;
|
||
goToEditMode: () => void;
|
||
}
|
||
|
||
export default function SingleEventCountdown({ subscribedEvent, goToEditMode }: SingleEventCountdownProps) {
|
||
const { mainSource, secondarySource, showExpected } = useCountdownOptions();
|
||
const showFab = useFadeOutOnInactivity(true);
|
||
const { data: reportData } = useReport();
|
||
|
||
const { offset, currentDay, actualStart, plannedStart, mode } = useExpectedStartData();
|
||
const { totalGap, isLinkedToLoaded } = subscribedEvent;
|
||
const expectedStart = getExpectedStart(subscribedEvent, {
|
||
currentDay,
|
||
totalGap,
|
||
actualStart,
|
||
plannedStart,
|
||
isLinkedToLoaded,
|
||
offset,
|
||
mode,
|
||
});
|
||
|
||
const expectedEnd = getExpectedEnd(subscribedEvent, expectedStart, currentDay);
|
||
|
||
const { endedAt } = reportData[subscribedEvent.reportId ?? subscribedEvent.id] ?? { endedAt: null };
|
||
const countdownEvent = { ...subscribedEvent, expectedStart, endedAt, expectedEnd };
|
||
const titleTmp = getPropertyValue(subscribedEvent, mainSource ?? 'title');
|
||
const title = titleTmp?.length ? titleTmp : ' '; // insert utf-8 empty space to avoid the line collapsing;
|
||
// while a group is live, surface the running event's title as the secondary line
|
||
const liveTitle = subscribedEvent.isGroup && subscribedEvent.liveEntry ? subscribedEvent.liveEntry.title : undefined;
|
||
const secondaryData = liveTitle ?? getPropertyValue(subscribedEvent, secondarySource);
|
||
|
||
return (
|
||
<div className='single-container' data-testid='countdown-event'>
|
||
<SubscriptionStatus event={countdownEvent} />
|
||
<div className='event__title' style={{ borderColor: countdownEvent.colour }}>
|
||
<ScheduleTime event={countdownEvent} showExpected={showExpected} />
|
||
{title}
|
||
{secondaryData && <div className='secondary'>{secondaryData}</div>}
|
||
</div>
|
||
<div className={cx(['fab-container', !showFab && 'fab-container--hidden'])}>
|
||
<Button variant='primary' size='xlarge' onClick={goToEditMode}>
|
||
<IoPencil /> Edit
|
||
</Button>
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
interface SubscriptionStatusProps {
|
||
event: CountdownEvent;
|
||
}
|
||
|
||
function SubscriptionStatus({ event }: SubscriptionStatusProps) {
|
||
const { status, statusDisplay, timeDisplay } = useSubscriptionDisplayData(event);
|
||
|
||
return (
|
||
<>
|
||
<div className='event__status'>{statusDisplay}</div>
|
||
{status === 'done' ? (
|
||
<SuperscriptTime className='event__timer' time={timeDisplay} />
|
||
) : (
|
||
<div className='event__timer'>{timeDisplay}</div>
|
||
)}
|
||
</>
|
||
);
|
||
}
|