mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-15 12:23:51 +00:00
@@ -16,5 +16,5 @@ export default function useProjectData() {
|
||||
networkMode: 'always',
|
||||
});
|
||||
|
||||
return { data, status, isFetching, isError, refetch };
|
||||
return { data: data ?? projectDataPlaceholder, status, isFetching, isError, refetch };
|
||||
}
|
||||
|
||||
@@ -120,3 +120,14 @@ export const useTimer = () => {
|
||||
};
|
||||
|
||||
export const setClientName = (newName: string) => socketSendJson('set-client-name', newName);
|
||||
|
||||
export const useRuntimeOverview = () => {
|
||||
const featureSelector = (state: RuntimeStore) => ({
|
||||
playback: state.playback,
|
||||
clock: state.timer.clock,
|
||||
numEvents: state.loaded.numEvents,
|
||||
selectedEventIndex: state.loaded.selectedEventIndex,
|
||||
});
|
||||
|
||||
return useRuntimeStore(featureSelector, deepCompare);
|
||||
};
|
||||
|
||||
@@ -34,18 +34,13 @@ $playback-width: 26rem;
|
||||
|
||||
display: grid;
|
||||
grid-template-columns: $menu-width auto;
|
||||
grid-template-rows: 2rem 1fr;
|
||||
grid-template-rows: 3rem 1fr;
|
||||
grid-template-areas:
|
||||
'menu overview'
|
||||
'menu main';
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.overview {
|
||||
grid-area: overview;
|
||||
background-color: $white-10;
|
||||
}
|
||||
|
||||
.panelContainer {
|
||||
grid-area: main;
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import MenuBar from '../menu/MenuBar';
|
||||
import AboutModal from '../modals/about-modal/AboutModal';
|
||||
import QuickStart from '../modals/quick-start/QuickStart';
|
||||
import UploadModal from '../modals/upload-modal/UploadModal';
|
||||
import Overview from '../overview/Overview';
|
||||
|
||||
import styles from './Editor.module.scss';
|
||||
|
||||
@@ -98,12 +99,7 @@ export default function Editor() {
|
||||
<Info />
|
||||
</div>
|
||||
)}
|
||||
<div className={styles.overview}>
|
||||
<ErrorBoundary></ErrorBoundary>
|
||||
{
|
||||
// TODO: the information about the event
|
||||
}
|
||||
</div>
|
||||
<Overview />
|
||||
</div>
|
||||
<EventEditor />
|
||||
</>
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { useInfoPanel } from '../../common/hooks/useSocket';
|
||||
import { useEditorSettings } from '../../common/stores/editorSettings';
|
||||
|
||||
import InfoHeader from './info-header/InfoHeader';
|
||||
import CollapsableInfo from './CollapsableInfo';
|
||||
import InfoLogger from './InfoLogger';
|
||||
import InfoNif from './InfoNif';
|
||||
@@ -25,15 +24,8 @@ export default function Info() {
|
||||
note: data.eventNext?.note || '',
|
||||
};
|
||||
|
||||
const selected = !data.numEvents
|
||||
? 'No events'
|
||||
: `Event ${data.selectedEventIndex !== null ? data.selectedEventIndex + 1 : '-'} / ${
|
||||
data.numEvents ? data.numEvents : '-'
|
||||
}`;
|
||||
|
||||
return (
|
||||
<>
|
||||
<InfoHeader selected={selected} />
|
||||
{showNif && (
|
||||
<CollapsableInfo title='Network Info'>
|
||||
<InfoNif />
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
import useProjectData from '../../../common/hooks-query/useProjectData';
|
||||
|
||||
import style from '../Info.module.scss';
|
||||
|
||||
export default function InfoHeader({ selected }: { selected: string }) {
|
||||
const { data } = useProjectData();
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={style.panelHeader}>
|
||||
<span className={style.title}>{data?.title || ''}</span>
|
||||
<span className={style.selected}>{selected}</span>
|
||||
</div>
|
||||
<div className={style.description}>{data?.description || ''}</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
@use '../../theme/ontimeColours' as *;
|
||||
@use '../../theme/v2Styles' as *;
|
||||
|
||||
.overview {
|
||||
grid-area: overview;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: start;
|
||||
font-size: $inner-section-text-size;
|
||||
gap: 2rem;
|
||||
padding-right: 0.5rem;
|
||||
}
|
||||
|
||||
.titles {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 1.5rem;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.description {
|
||||
font-size: 1rem;
|
||||
color: $label-gray;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.inline {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.25rem;
|
||||
}
|
||||
|
||||
@mixin indicator($bg-color) {
|
||||
&::before {
|
||||
content: '';
|
||||
background-color: $bg-color;
|
||||
display: inline-flex;
|
||||
height: 0.75em;
|
||||
width: 0.75em;
|
||||
vertical-align: middle;
|
||||
margin-right: 0.25rem;
|
||||
}
|
||||
}
|
||||
|
||||
.start {
|
||||
@include indicator($green-500);
|
||||
}
|
||||
|
||||
.end {
|
||||
@include indicator($red-500);
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
import { Tooltip } from '@chakra-ui/react';
|
||||
|
||||
import ErrorBoundary from '../../common/components/error-boundary/ErrorBoundary';
|
||||
import PlaybackIcon from '../../common/components/playback-icon/PlaybackIcon';
|
||||
import { useRuntimeOverview } from '../../common/hooks/useSocket';
|
||||
import useProjectData from '../../common/hooks-query/useProjectData';
|
||||
import { formatTime } from '../../common/utils/time';
|
||||
|
||||
import styles from './Overview.module.scss';
|
||||
|
||||
export default function Overview() {
|
||||
return (
|
||||
<div className={styles.overview}>
|
||||
<ErrorBoundary>
|
||||
<TitlesOverview />
|
||||
<div className={styles.clocks}>
|
||||
<Tooltip label='Planned start'>
|
||||
<div className={styles.start}>Planned start</div>
|
||||
</Tooltip>
|
||||
<Tooltip label='Actual start'>
|
||||
<div className={styles.start}>Actual start</div>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<RuntimeOverview />
|
||||
<div className={styles.clocks}>
|
||||
<Tooltip label='Planned end'>
|
||||
<div className={styles.end}>Planned end</div>
|
||||
</Tooltip>
|
||||
<Tooltip label='Expected end'>
|
||||
<div className={styles.end}>Expected end</div>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</ErrorBoundary>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function TitlesOverview() {
|
||||
const { data } = useProjectData();
|
||||
|
||||
return (
|
||||
<div className={styles.titles}>
|
||||
<div className={styles.title}>{data.title}</div>
|
||||
<div className={styles.description}>{data.description}</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function RuntimeOverview() {
|
||||
const { playback, clock, numEvents, selectedEventIndex } = useRuntimeOverview();
|
||||
|
||||
const current = selectedEventIndex !== null ? selectedEventIndex + 1 : '-';
|
||||
const ofTotal = numEvents || '-';
|
||||
|
||||
const display = formatTime(clock, {
|
||||
showSeconds: true,
|
||||
});
|
||||
|
||||
return (
|
||||
<div className={styles.clocks}>
|
||||
<div className={styles.inline}>
|
||||
<PlaybackIcon state={playback} skipTooltip />
|
||||
{display}
|
||||
</div>
|
||||
<div className={styles.inline}>
|
||||
<span>{`(${current} / ${ofTotal})`}</span>
|
||||
Over / Under
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user