mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-17 21:24:11 +00:00
feat: milestones
This commit is contained in:
committed by
Carlos Valente
parent
a7ae8598db
commit
f2913971db
+45
-1
@@ -1,7 +1,15 @@
|
||||
import { RefObject, useEffect } from 'react';
|
||||
import { useQueryClient } from '@tanstack/react-query';
|
||||
import { RowModel, Table } from '@tanstack/react-table';
|
||||
import { isOntimeBlock, isOntimeDelay, isOntimeEvent, OntimeBlock, OntimeEntry, Rundown } from 'ontime-types';
|
||||
import {
|
||||
isOntimeBlock,
|
||||
isOntimeDelay,
|
||||
isOntimeEvent,
|
||||
isOntimeMilestone,
|
||||
OntimeBlock,
|
||||
OntimeEntry,
|
||||
Rundown,
|
||||
} from 'ontime-types';
|
||||
import { colourToHex, cssOrHexToColour } from 'ontime-utils';
|
||||
|
||||
import { RUNDOWN } from '../../../../common/api/constants';
|
||||
@@ -13,6 +21,7 @@ import { usePersistedCuesheetOptions } from '../../cuesheet.options';
|
||||
import BlockRow from './BlockRow';
|
||||
import DelayRow from './DelayRow';
|
||||
import EventRow from './EventRow';
|
||||
import MilestoneRow from './MilestoneRow';
|
||||
import { cleanup } from './rowObserver';
|
||||
|
||||
interface CuesheetBodyProps {
|
||||
@@ -90,6 +99,41 @@ export default function CuesheetBody({ rowModel, selectedRef, table }: CuesheetB
|
||||
}
|
||||
return <DelayRow key={key} duration={delayVal} parentBgColour={parentBgColour} />;
|
||||
}
|
||||
if (isOntimeMilestone(entry)) {
|
||||
if (isPast && hidePast) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let rowBgColour: string | undefined;
|
||||
if (entry.colour) {
|
||||
// the colour is user defined and might be invalid
|
||||
const accessibleBackgroundColor = cssOrHexToColour(getAccessibleColour(entry.colour).backgroundColor);
|
||||
if (accessibleBackgroundColor !== null) {
|
||||
rowBgColour = colourToHex({
|
||||
...accessibleBackgroundColor,
|
||||
alpha: accessibleBackgroundColor.alpha * 0.25,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
let parentBgColour: string | null = null;
|
||||
if (entry.parent) {
|
||||
const rundown = queryClient.getQueryData<Rundown>(RUNDOWN);
|
||||
const parentEntry = rundown?.entries[entry.parent];
|
||||
parentBgColour = (parentEntry as OntimeBlock).colour ?? null;
|
||||
}
|
||||
|
||||
return (
|
||||
<MilestoneRow
|
||||
key={key}
|
||||
isPast={isPast}
|
||||
parentBgColour={parentBgColour}
|
||||
rowBgColour={rowBgColour}
|
||||
rowId={row.id}
|
||||
table={table}
|
||||
/>
|
||||
);
|
||||
}
|
||||
if (isOntimeEvent(entry)) {
|
||||
eventIndex++;
|
||||
const isSelected = key === selectedEventId;
|
||||
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
@import "../CuesheetTable.module.scss";
|
||||
|
||||
.milestoneRow {
|
||||
background: color-mix(in srgb, transparent 92%, var(--user-bg, $gray-500) 8%);
|
||||
border-left: 4px solid var(--user-bg, $gray-500);
|
||||
|
||||
&:hover {
|
||||
outline: 1px solid $blue-500;
|
||||
outline-offset: -1px;
|
||||
background: color-mix(in srgb, transparent 80%, var(--user-bg, $gray-500) 20%);
|
||||
}
|
||||
|
||||
td {
|
||||
background-color: $gray-1250;
|
||||
border-radius: 2px;
|
||||
}
|
||||
}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
import { IoEllipsisHorizontal } from 'react-icons/io5';
|
||||
import { useSessionStorage } from '@mantine/hooks';
|
||||
import { flexRender, Table } from '@tanstack/react-table';
|
||||
import { OntimeEntry } from 'ontime-types';
|
||||
|
||||
import IconButton from '../../../../common/components/buttons/IconButton';
|
||||
import { cx, enDash } from '../../../../common/utils/styleUtils';
|
||||
import { AppMode, sessionKeys } from '../../../../ontimeConfig';
|
||||
import { usePersistedCuesheetOptions } from '../../cuesheet.options';
|
||||
|
||||
import style from './MilestoneRow.module.scss';
|
||||
|
||||
interface MilestoneRowProps {
|
||||
isPast: boolean;
|
||||
parentBgColour: string | null;
|
||||
rowBgColour?: string;
|
||||
rowId: string;
|
||||
table: Table<OntimeEntry>;
|
||||
}
|
||||
|
||||
export default function MilestoneRow({ isPast, parentBgColour, rowBgColour, rowId, table }: MilestoneRowProps) {
|
||||
const hideIndexColumn = usePersistedCuesheetOptions((state) => state.hideIndexColumn);
|
||||
const [cuesheetMode] = useSessionStorage<AppMode>({
|
||||
key: sessionKeys.cuesheetMode,
|
||||
defaultValue: AppMode.Edit,
|
||||
});
|
||||
|
||||
return (
|
||||
<tr
|
||||
className={cx([style.milestoneRow, Boolean(parentBgColour) && style.hasParent])}
|
||||
style={{
|
||||
opacity: `${isPast ? '0.2' : '1'}`,
|
||||
'--user-bg': parentBgColour ?? 'transparent',
|
||||
}}
|
||||
data-testid='cuesheet-milestone'
|
||||
>
|
||||
{cuesheetMode === AppMode.Edit && (
|
||||
<td className={style.actionColumn} tabIndex={-1} role='cell'>
|
||||
<IconButton aria-label='Options' variant='subtle-white' size='small' onClick={() => undefined}>
|
||||
<IoEllipsisHorizontal />
|
||||
</IconButton>
|
||||
</td>
|
||||
)}
|
||||
{!hideIndexColumn && (
|
||||
<td className={style.indexColumn} tabIndex={-1} role='cell'>
|
||||
{enDash}
|
||||
</td>
|
||||
)}
|
||||
{table
|
||||
.getRow(rowId)
|
||||
.getVisibleCells()
|
||||
.map((cell) => {
|
||||
const canRender =
|
||||
cell.column.id !== 'duration' && cell.column.id !== 'timeStart' && cell.column.id !== 'timeEnd';
|
||||
return (
|
||||
<td
|
||||
key={cell.id}
|
||||
style={{
|
||||
width: `calc(var(--col-${cell.column.id}-size) * 1px)`,
|
||||
backgroundColor: rowBgColour,
|
||||
}}
|
||||
tabIndex={-1}
|
||||
role='cell'
|
||||
>
|
||||
{canRender && flexRender(cell.column.columnDef.cell, cell.getContext())}
|
||||
</td>
|
||||
);
|
||||
})}
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user