mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-13 19:33:46 +00:00
52cae1e22f
Co-authored-by: Carlos Valente <carlosvalente@pm.me>
96 lines
3.5 KiB
TypeScript
96 lines
3.5 KiB
TypeScript
import { OntimeView } from 'ontime-types';
|
|
import { useMemo } from 'react';
|
|
|
|
import EmptyPage from '../../common/components/state/EmptyPage';
|
|
import ViewLogo from '../../common/components/view-logo/ViewLogo';
|
|
import ViewParamsEditor from '../../common/components/view-params-editor/ViewParamsEditor';
|
|
import { useAutoTickingClock } from '../../common/hooks/useAutoTickingClock';
|
|
import { useSelectedEventId } from '../../common/hooks/useSocket';
|
|
import { useWindowTitle } from '../../common/hooks/useWindowTitle';
|
|
import { formatTime, getDefaultFormat } from '../../common/utils/time';
|
|
import { useTranslation } from '../../translation/TranslationProvider';
|
|
import Loader from '../common/loader/Loader';
|
|
import SuperscriptTime from '../common/superscript-time/SuperscriptTime';
|
|
import Timeline from './Timeline';
|
|
import { getTimelineOptions, useTimelineOptions } from './timeline.options';
|
|
import { getUpcomingEvents, useScopedRundown } from './timeline.utils';
|
|
import TimelineSections from './TimelineSections';
|
|
import { TimelineData, useTimelineData } from './useTimelineData';
|
|
|
|
import './TimelinePage.scss';
|
|
|
|
export default function TimelinePageLoader() {
|
|
const { data, status } = useTimelineData();
|
|
|
|
useWindowTitle('Timeline');
|
|
|
|
if (status === 'pending') {
|
|
return <Loader />;
|
|
}
|
|
|
|
if (status === 'error') {
|
|
return <EmptyPage text='There was an error fetching data, please refresh the page.' />;
|
|
}
|
|
|
|
return <TimelinePage {...data} />;
|
|
}
|
|
|
|
function TimelinePage({ events, customFields, projectData, settings }: TimelineData) {
|
|
const selectedEventId = useSelectedEventId();
|
|
const { mainSource, timeformat } = useTimelineOptions();
|
|
const { getLocalizedString } = useTranslation();
|
|
|
|
// holds copy of the rundown with only relevant events
|
|
const { scopedRundown, firstStart, totalDuration } = useScopedRundown(events, selectedEventId);
|
|
|
|
// gather card options
|
|
const { now, next, followedBy } = useMemo(() => {
|
|
return getUpcomingEvents(scopedRundown, selectedEventId);
|
|
}, [scopedRundown, selectedEventId]);
|
|
|
|
// populate options
|
|
const defaultFormat = getDefaultFormat(settings?.timeFormat);
|
|
const progressOptions = useMemo(() => getTimelineOptions(defaultFormat, customFields), [defaultFormat, customFields]);
|
|
|
|
const hasContent = totalDuration > 0;
|
|
|
|
return (
|
|
<div className='timeline' data-testid='timeline-view'>
|
|
<ViewParamsEditor target={OntimeView.Timeline} viewOptions={progressOptions} />
|
|
<div className='project-header'>
|
|
{projectData?.logo && <ViewLogo name={projectData.logo} className='logo' />}
|
|
<div className='title'>{projectData.title}</div>
|
|
<TimelineClock timeformat={timeformat} />
|
|
</div>
|
|
|
|
<TimelineSections now={now} next={next} followedBy={followedBy} mainSource={mainSource} />
|
|
|
|
{hasContent ? (
|
|
<Timeline
|
|
firstStart={firstStart}
|
|
rundown={scopedRundown}
|
|
selectedEventId={selectedEventId}
|
|
totalDuration={totalDuration}
|
|
/>
|
|
) : (
|
|
<EmptyPage text={getLocalizedString('common.no_data')} />
|
|
)}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function TimelineClock({ timeformat }: { timeformat: string | null }) {
|
|
const { getLocalizedString } = useTranslation();
|
|
const clock = useAutoTickingClock();
|
|
|
|
// gather timer data
|
|
const formattedClock = formatTime(clock, { override: timeformat });
|
|
|
|
return (
|
|
<div className='clock-container'>
|
|
<div className='label'>{getLocalizedString('common.time_now')}</div>
|
|
<SuperscriptTime time={formattedClock} className='time' />
|
|
</div>
|
|
);
|
|
}
|