refactor: extract cuesheet permissions

This commit is contained in:
Carlos Valente
2026-02-20 20:49:08 +01:00
committed by Carlos Valente
parent 5be504ce8f
commit df588b8845
9 changed files with 290 additions and 75 deletions
@@ -34,13 +34,24 @@ import { useColumnOrder, useColumnSizes, useColumnVisibility } from './useColumn
import style from './CuesheetTable.module.scss';
interface CuesheetTableProps {
type CuesheetTableBaseProps = {
columns: ColumnDef<ExtendedEntry>[];
cuesheetMode: AppMode;
tableRoot?: 'editor' | 'cuesheet';
}
};
export default function CuesheetTable({ columns, cuesheetMode, tableRoot = 'cuesheet' }: CuesheetTableProps) {
type EditorCuesheetTableProps = CuesheetTableBaseProps & {
tableRoot: 'editor';
setCuesheetMode?: undefined;
};
type ViewCuesheetTableProps = CuesheetTableBaseProps & {
tableRoot: 'cuesheet';
setCuesheetMode: (mode: AppMode) => void;
};
type CuesheetTableProps = EditorCuesheetTableProps | ViewCuesheetTableProps;
export default function CuesheetTable({ columns, cuesheetMode, tableRoot, setCuesheetMode }: CuesheetTableProps) {
const { data, status } = useFlatRundownWithMetadata();
const { updateEntry, updateTimer } = useEntryActionsContext();
@@ -206,17 +217,25 @@ export default function CuesheetTable({ columns, cuesheetMode, tableRoot = 'cues
return <EmptyPage text='Loading...' />;
}
// control components need different implementations for handling permissions
const TableRootSettings = tableRoot === 'editor' ? EditorTableSettings : CuesheetTableSettings;
return (
<>
<TableRootSettings
columns={allLeafColumns}
handleResetResizing={resetColumnResizing}
handleResetReordering={resetColumnOrder}
handleClearToggles={setAllVisible}
/>
{tableRoot === 'editor' ? (
<EditorTableSettings
columns={allLeafColumns}
handleResetResizing={resetColumnResizing}
handleResetReordering={resetColumnOrder}
handleClearToggles={setAllVisible}
/>
) : (
<CuesheetTableSettings
columns={allLeafColumns}
cuesheetMode={cuesheetMode}
setCuesheetMode={setCuesheetMode}
handleResetResizing={resetColumnResizing}
handleResetReordering={resetColumnOrder}
handleClearToggles={setAllVisible}
/>
)}
<TableVirtuoso
ref={virtuosoRef}
data={data}
@@ -7,6 +7,7 @@ import DelayIndicator from '../../../../common/components/delay-indicator/DelayI
import type { ExtendedEntry } from '../../../../common/utils/rundownMetadata';
import { formatDuration, formatTime } from '../../../../common/utils/time';
import { AppMode } from '../../../../ontimeConfig';
import { getCuesheetColumnAccessPolicy } from '../../cuesheet.policies';
import DurationInput from './DurationInput';
import EditableImage from './EditableImage';
@@ -257,15 +258,7 @@ export function makeCuesheetColumns(
preset: URLPreset | undefined,
): ColumnDef<ExtendedEntry>[] {
const columnsDef: ColumnDef<ExtendedEntry>[] = [];
const modeAllowsWrite = cuesheetMode === AppMode.Edit;
const fullRead = preset ? preset.options?.read === 'full' : true;
const fullWrite = preset ? preset.options?.write === 'full' : true;
const canWriteKeys = preset?.options?.write ? new Set(preset.options.write.split(',')) : new Set<string>();
const canReadKeys = preset?.options?.read ? new Set(preset.options.read.split(',')) : new Set<string>();
// helpers to check read/write for a given key
const canRead = (key: string) => fullRead || canReadKeys.has(key);
const canWrite = (key: string) => modeAllowsWrite && (fullWrite || canWriteKeys.has(key));
const { canRead, canWrite } = getCuesheetColumnAccessPolicy(preset, cuesheetMode);
if (canRead('flag')) {
columnsDef.push({
@@ -1,20 +1,18 @@
import { ReactNode, use } from 'react';
import { ReactNode } from 'react';
import { IoBookOutline, IoChevronDown, IoOptions } from 'react-icons/io5';
import { Popover } from '@base-ui/react/popover';
import { Toggle } from '@base-ui/react/toggle';
import { ToggleGroup } from '@base-ui/react/toggle-group';
import { Toolbar } from '@base-ui/react/toolbar';
import { useSessionStorage } from '@mantine/hooks';
import type { Column } from '@tanstack/react-table';
import Button from '../../../../common/components/buttons/Button';
import Checkbox from '../../../../common/components/checkbox/Checkbox';
import * as Editor from '../../../../common/components/editor-utils/EditorUtils';
import PopoverContents from '../../../../common/components/popover/Popover';
import { PresetContext } from '../../../../common/context/PresetContext';
import type { ExtendedEntry } from '../../../../common/utils/rundownMetadata';
import { cx } from '../../../../common/utils/styleUtils';
import { AppMode, sessionKeys } from '../../../../ontimeConfig';
import { AppMode } from '../../../../ontimeConfig';
import { CuesheetOptions, usePersistedCuesheetOptions } from '../../cuesheet.options';
import { useCuesheetPermissions } from '../../useTablePermissions';
@@ -24,6 +22,8 @@ import style from './CuesheetTableSettings.module.scss';
interface CuesheetTableSettingsProps {
columns: Column<ExtendedEntry, unknown>[];
cuesheetMode: AppMode;
setCuesheetMode: (mode: AppMode) => void;
handleResetResizing: () => void;
handleResetReordering: () => void;
handleClearToggles: () => void;
@@ -42,20 +42,16 @@ export interface ColumnSettingsProps {
export default function CuesheetTableSettings({
columns,
cuesheetMode,
setCuesheetMode,
handleResetResizing,
handleResetReordering,
handleClearToggles,
}: CuesheetTableSettingsProps) {
const canChangeMode = useCuesheetPermissions((state) => state.canChangeMode);
const canShare = useCuesheetPermissions((state) => state.canShare);
const preset = use(PresetContext);
const options = usePersistedCuesheetOptions();
const [cuesheetMode, setCuesheetMode] = useSessionStorage({
key: preset ? `${preset.alias}${sessionKeys.cuesheetMode}` : sessionKeys.cuesheetMode,
defaultValue: preset ? AppMode.Run : AppMode.Edit,
});
const toggleCuesheetMode = (mode: AppMode[]) => {
// we need to stop user from deselecting a mode
const newValue = mode.at(0);