mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-31 20:09:11 +00:00
112 lines
3.4 KiB
TypeScript
112 lines
3.4 KiB
TypeScript
import { Table, flexRender } from '@tanstack/react-table';
|
|
import { EntryId, SupportedEntry } from 'ontime-types';
|
|
import { colourToHex, cssOrHexToColour } from 'ontime-utils';
|
|
import { CSSProperties, memo, useMemo } from 'react';
|
|
import { IoEllipsisHorizontal } from 'react-icons/io5';
|
|
|
|
import IconButton from '../../../../common/components/buttons/IconButton';
|
|
import type { ExtendedEntry } from '../../../../common/utils/rundownMetadata';
|
|
import { cx, enDash, getAccessibleColour } from '../../../../common/utils/styleUtils';
|
|
import { AppMode } from '../../../../ontimeConfig';
|
|
import { useCuesheetTableMenu } from '../cuesheet-table-menu/useCuesheetTableMenu';
|
|
|
|
import style from './MilestoneRow.module.scss';
|
|
|
|
interface MilestoneRowProps {
|
|
entryId: EntryId;
|
|
isPast: boolean;
|
|
parentBgColour?: string;
|
|
parentId: EntryId | null;
|
|
colour: string;
|
|
rowId: string;
|
|
rowIndex: number;
|
|
table: Table<ExtendedEntry>;
|
|
injectedStyles?: CSSProperties;
|
|
hasCursor?: boolean;
|
|
}
|
|
|
|
export default memo(MilestoneRow);
|
|
function MilestoneRow({
|
|
entryId,
|
|
isPast,
|
|
parentBgColour,
|
|
parentId,
|
|
colour,
|
|
rowId,
|
|
rowIndex,
|
|
hasCursor,
|
|
table,
|
|
injectedStyles,
|
|
...virtuosoProps
|
|
}: MilestoneRowProps) {
|
|
const { cuesheetMode, hideIndexColumn } = table.options.meta?.options ?? {
|
|
cuesheetMode: AppMode.Edit,
|
|
hideIndexColumn: false,
|
|
};
|
|
|
|
const openMenu = useCuesheetTableMenu((store) => store.openMenu);
|
|
|
|
const rowBgColour = useMemo(() => {
|
|
if (!colour) return undefined;
|
|
const accessibleBg = cssOrHexToColour(getAccessibleColour(colour).backgroundColor);
|
|
if (accessibleBg === null) return undefined;
|
|
return colourToHex({ ...accessibleBg, alpha: accessibleBg.alpha * 0.25 });
|
|
}, [colour]);
|
|
|
|
return (
|
|
<tr
|
|
className={cx([style.milestoneRow, Boolean(parentBgColour) && style.hasParent])}
|
|
style={{
|
|
...injectedStyles,
|
|
opacity: `${isPast ? '0.2' : '1'}`,
|
|
'--user-bg': parentBgColour ?? 'transparent',
|
|
}}
|
|
data-testid='cuesheet-milestone'
|
|
data-cursor={hasCursor}
|
|
{...virtuosoProps}
|
|
>
|
|
{cuesheetMode === AppMode.Edit && (
|
|
<td className={style.actionColumn} tabIndex={-1} role='cell'>
|
|
<IconButton
|
|
aria-label='Options'
|
|
variant='ghosted-white'
|
|
size='small'
|
|
onClick={(e) => {
|
|
const rect = e.currentTarget.getBoundingClientRect();
|
|
const yPos = 8 + rect.y + rect.height / 2;
|
|
openMenu({ x: rect.x, y: yPos }, entryId, SupportedEntry.Milestone, rowIndex, parentId, null);
|
|
}}
|
|
>
|
|
<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,
|
|
opacity: canRender ? 1 : 0.4,
|
|
}}
|
|
tabIndex={-1}
|
|
>
|
|
{canRender && flexRender(cell.column.columnDef.cell, cell.getContext())}
|
|
</td>
|
|
);
|
|
})}
|
|
</tr>
|
|
);
|
|
}
|