Skip to content

refactor: allow secondary rundowns#2086

Open
cpvalente wants to merge 7 commits into
masterfrom
cuesheet-rundown
Open

refactor: allow secondary rundowns#2086
cpvalente wants to merge 7 commits into
masterfrom
cuesheet-rundown

Conversation

@cpvalente
Copy link
Copy Markdown
Owner

No description provided.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 11, 2026

Review Change Stack

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: defbbd96-119b-4521-9967-ea42a247afed

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

This PR enables multi-rundown editing by refactoring both client and server to support explicit rundown ID scoping. The client gains ID-based rundown fetching with scoped selection UI, while the server makes all mutations require explicit rundownId parameters and async transaction handling.

Changes

Client-side multi-rundown scoping and UI

Layer / File(s) Summary
Rundown API and data hooks
apps/client/src/common/api/rundown.ts, apps/client/src/common/hooks-query/useRundown.ts, apps/client/src/common/hooks-query/useScopedRundown.ts
New fetchRundown(rundownId) function validates and fetches rundowns by ID. RundownSource type and useScopedRundown/useLoadedRundownSource hooks provide scoped rundown data (flat entries, status, selected event) for display and mutation.
Scoped entry actions
apps/client/src/common/hooks/useEntryAction.ts
useEntryActions delegates to internal useEntryActionsForRundown and new useScopedEntryActions(rundownId) hook scopes entry mutations to a specific rundown instead of always using the loaded one.
Rundown selection and background edit navigation
apps/client/src/views/cuesheet/useCuesheetRundownSelection.ts, apps/client/src/features/app-settings/panel/manage-panel/ManageRundowns.tsx
useCuesheetRundownSelection manages session-storage-persisted rundown selection with a FOLLOW_LOADED_RUNDOWN_ID sentinel, resolver fallback logic, and useDirectLinkToBackgroundEdit hook for direct navigation to background editing context.
CuesheetPage integration of scoped rundown selection
apps/client/src/views/cuesheet/CuesheetPage.tsx
Refactors to use cuesheet-specific selection (useCuesheetRundownSelection) and scoped rundown data (useScopedRundown, useScopedEntryActions), wiring selection state and source through component hierarchy.
CuesheetTableWrapper with rundown selection UI
apps/client/src/views/cuesheet/CuesheetTableWrapper.tsx
Transforms into prop-driven wrapper receiving RundownSource, selection state, and project rundowns. Computes isCurrentRundown for mode policy and renders new RundownSelect dropdown to switch between available rundowns.
CuesheetTable props-driven refactoring
apps/client/src/views/cuesheet/cuesheet-table/CuesheetTable.tsx
Removes internal useFlatRundownWithMetadata and useSelectedEventId hooks, accepts source: RundownSource prop for flat rundown data, and updates scrolling/row rendering to use provided flatRundown instead of internal state.
CuesheetTableHeaderToolbar refactoring and styling
apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-settings/CuesheetTableHeaderToolbar.tsx, apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-settings/CuesheetTableSettings.module.scss
Renames component to CuesheetTableHeaderToolbar, accepts optionsStore and modeControls (with isCurrentRundown gate), wires ViewSettings checkboxes to optionsStore, makes ColumnSettings internal. Adds background-rundown styling with blink animation and updated radio button disabled state.
Entry editor and modal prop wiring
apps/client/src/features/rundown/entry-editor/CuesheetEventEditor.tsx, apps/client/src/views/cuesheet/cuesheet-edit-modal/EntryEditModal.tsx, apps/client/src/features/rundown/RundownExport.tsx, apps/client/src/features/rundown/rundown-table/RundownTable.tsx, apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/EditableImage.tsx
Propagates rundown data as props through modal and editor components instead of internal fetching. CuesheetEventEditor reads from prop-provided rundown, EntryEditModal accepts rundown, RundownExport and RundownTable wire loaded source through hierarchy. EditableImage hides when readonly and empty.
Supporting client changes and tests
apps/client/src/features/rundown/useEventSelection.ts, apps/client/src/views/cuesheet/useApplyCuesheetPolicy.ts, apps/client/src/common/utils/socket.ts, apps/client/src/views/cuesheet/__tests__/*, apps/client/src/views/cuesheet/CuesheetPage.module.scss
Updates event selection to query by rundown ID instead of current key. Refactors policy hook to accept canRunMode parameter. Socket invalidation handles new RefetchKey.ProjectRundowns case. Adds test coverage for rundown selection helpers and mode computation. Adds responsive .rundownSelect CSS class.

Server-side multi-rundown mutation scoping

Layer / File(s) Summary
Rundown processing and DAO transaction async support
apps/server/src/api-data/rundown/rundown.dao.ts, apps/server/src/api-data/rundown/rundown.parser.ts, apps/server/src/api-data/rundown/__mocks__/rundown.mocks.ts
createTransaction.commit() becomes async, supports optional rundown processing, persists changes via setRundown/setCustomFields, and returns metadata (null for background rundowns). applyDelay uses rundown's own flatOrder. New getProcessedRundown(rundownId) loads and processes client-facing shape. makeRundownMetadata accepts optional {mutate} flag for in-place processing. Mock makeRundown computes flatOrder when omitted.
Service mutations with explicit rundownId
apps/server/src/api-data/rundown/rundown.service.ts
All entry mutations (addEntry, editEntry, batchEditEntries, deleteEntries, deleteAllEntries, reorderEntry, renumberEntries, applyDelay, swapEvents, cloneEntry, groupEntries, ungroupEntries) now accept explicit rundownId as first parameter, create scoped transactions, await async commits, and return committed results. New createNewRundown(title) creates and persists empty rundown. Notifications and timer updates now handle nullable metadata.
Router updates for scoped mutations
apps/server/src/api-data/rundown/rundown.router.ts
Passes rundownId from URL params to all service methods. Removes validateRundownMutation middleware. Adds GET /:id endpoint using getProcessedRundown with 404 handling. Simplifies POST / rundown creation via createNewRundown.
Validation middleware cleanup
apps/server/src/api-data/rundown/rundown.validation.ts
Removes validateRundownMutation middleware that enforced implicit current-rundown scoping. Simplifies imports by removing Express request/response type dependencies.
Integration controller updates
apps/server/src/api-integration/integration.controller.ts
Updates change action handler to retrieve current rundown ID alongside entries and pass it to editEntry for proper scoping of remote change payloads.
Server-side test coverage
apps/server/src/api-data/rundown/__tests__/rundown.dao.test.ts
Updates createTransaction test to handle async commits. Adds processRundown test validating delay computation. Adds applyDelay isolation test ensuring background rundowns mutate independently from loaded rundowns.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • cpvalente/ontime#2005: Both PRs update the client rundown caching/query-key wiring—main PR's socket refetch handling and rundown-cache invalidation build directly on the retrieved PR's dynamic getRundownQueryKey + query-key invalidation refactor.
  • cpvalente/ontime#1620: Both PRs modify the server rundown transaction/processing flow—specifically createTransaction, commit behavior, and processed rundown handling—so the main PR's async commit refactor is related to the retrieved PR's earlier work.
  • cpvalente/ontime#2068: The main PR's socket Refetch handling for RefetchKey.ProjectRundowns and maybeInvalidateRundownCache invalidation logic directly align with the retrieved PR's websocket payload changes to invalidate by rundownId.

Suggested labels

priority

Suggested reviewers

  • alex-Arc
  • Gwenitora
  • jwetzell
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning No description was provided by the author. Add a description explaining the refactoring: what secondary rundowns are, why they are needed, and how the changes enable this feature.
Docstring Coverage ⚠️ Warning Docstring coverage is 56.06% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely identifies the main change: enabling support for secondary/multiple rundowns alongside the current rundown system.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch cuesheet-rundown

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@cpvalente cpvalente force-pushed the cuesheet-rundown branch 4 times, most recently from ceb387a to b2691be Compare May 14, 2026 08:13
@alex-Arc alex-Arc force-pushed the cuesheet-rundown branch 3 times, most recently from a82c78a to 088ca1a Compare May 17, 2026 18:39
@alex-Arc alex-Arc force-pushed the cuesheet-rundown branch 3 times, most recently from b392900 to 9a2f65e Compare May 25, 2026 09:29
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🧹 Nitpick comments (2)
apps/client/src/views/cuesheet/cuesheet-table/CuesheetTable.tsx (1)

228-232: 💤 Low value

Consider simplifying the loading check.

The !flatRundown check is essentially dead code given that RundownSource.flatRundown is typed as ExtendedEntry[] (always an array, never undefined). The status === 'pending' check alone should suffice. However, this is a minor defensive coding pattern that doesn't cause harm.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/client/src/views/cuesheet/cuesheet-table/CuesheetTable.tsx` around lines
228 - 232, The loading check uses a redundant !flatRundown condition; since
RundownSource.flatRundown is typed as ExtendedEntry[] (always an array),
simplify isLoading to only check status === 'pending' by updating the isLoading
assignment (referencing isLoading, flatRundown, and status) and keep the
existing early return to EmptyPage unchanged.
apps/client/src/views/cuesheet/CuesheetTableWrapper.tsx (1)

58-68: 💤 Low value

Unnecessary fragment wrapper around single element.

The fragment wrapper <>...</> is redundant when there's only a single child element.

♻️ Suggested simplification
          insertElement={
-            <>
-              <RundownSelect
-                cuesheetMode={cuesheetMode}
-                selectedRundownId={selectedRundownId}
-                loadedRundownId={loadedRundownId}
-                setSelectedRundownId={setSelectedRundownId}
-                projectRundowns={projectRundowns}
-              />
-            </>
+            <RundownSelect
+              cuesheetMode={cuesheetMode}
+              selectedRundownId={selectedRundownId}
+              loadedRundownId={loadedRundownId}
+              setSelectedRundownId={setSelectedRundownId}
+              projectRundowns={projectRundowns}
+            />
          }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/client/src/views/cuesheet/CuesheetTableWrapper.tsx` around lines 58 -
68, The JSX fragment wrapping the single RundownSelect is redundant; in
CuesheetTableWrapper replace the insertElement prop value that currently uses
<>...</> with a direct JSX element (set insertElement={<RundownSelect ... />}),
keeping all props (cuesheetMode, selectedRundownId, loadedRundownId,
setSelectedRundownId, projectRundowns) unchanged and leaving RundownSelect as
the sole child.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/client/src/common/hooks/useEntryAction.ts`:
- Around line 73-75: The helper useScopedEntryActions currently maps a null
rundownId to an empty string which creates an explicit scoped key and bypasses
the fallback path in useEntryActionsForRundown; update useScopedEntryActions so
it forwards undefined (e.g. pass rundownId ?? undefined or conditional if null)
instead of '' and keep the parameter types compatible with
useEntryActionsForRundown (useScopedEntryActions(rundownId: string | null) =>
useEntryActionsForRundown(rundownId ?? undefined)) so the loaded-rundown
fallback path is preserved.

In `@apps/client/src/features/rundown/useEventSelection.ts`:
- Around line 140-142: The selection lookup in useEventSelection is hard-coded
to PROJECT_RUNDOWNS.loaded which can produce incorrect range selections for
background/secondary rundowns; instead accept or read an active rundownId
supplied by CuesheetTable (e.g., pass/set an active rundownId in
useEventSelection from CuesheetTable) and use that ID when calling
getRundownQueryKey(rundownId) and when computing shift/ctrl range logic; replace
usages of getQueryData<ProjectRundownsList>(PROJECT_RUNDOWNS)?.loaded with the
active rundownId parameter/state and ensure all selection computation in
useEventSelection uses that ID.

In
`@apps/client/src/views/cuesheet/__tests__/useCuesheetRundownSelection.test.ts`:
- Around line 10-16: Update the tests to match the actual
resolveSelectedRundownId signature: call
resolveSelectedRundownId(storedSelectedRundownId, availableRundownIds) (i.e.,
pass the Set as the second argument, not the loaded id) and change expectations
so the missing/invalid stored selection expects the FOLLOW_LOADED_RUNDOWN_ID
constant (use FOLLOW_LOADED_RUNDOWN_ID in assertions) instead of the string
'loaded'; keep resolveSelectedRundownId and FOLLOW_LOADED_RUNDOWN_ID as the
referenced symbols when changing the test cases.

In
`@apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-settings/CuesheetTableHeaderToolbar.tsx`:
- Line 70: The data-background-rundown attribute on Toolbar.Root is currently
set with !modeControls?.isCurrentRundown which evaluates to true when
modeControls is undefined; change the logic so the attribute is true only when
modeControls exists and isCurrentRundown is false (e.g., use modeControls ?
!modeControls.isCurrentRundown : false or Boolean(modeControls &&
!modeControls.isCurrentRundown)); update the Toolbar.Root prop (in
CuesheetTableHeaderToolbar.tsx) referencing modeControls and isCurrentRundown to
implement this explicit check so editor context doesn't show BACKGROUND EDIT
styling.

In
`@apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-settings/CuesheetTableSettings.module.scss`:
- Around line 11-12: Remove the unexpected blank line immediately preceding the
transition declaration in CuesheetTableSettings.module.scss so the rule reads
without an empty line before "transition: background-color 0.2s ease-in-out;";
edit the block containing the transition property to eliminate the extra newline
so Stylelint no longer flags the empty line before the transition declaration.

In `@apps/client/src/views/cuesheet/useCuesheetRundownSelection.ts`:
- Around line 15-20: The function resolveSelectedRundownId is assuming
availableRundownIds is a Set which causes a TypeError in tests that pass arrays
or other iterables; update the function to accept a wider type (e.g.,
Set<string> | string[] | Iterable<string>) or normalize the input at the start
(convert availableRundownIds to a Set) before calling .has, then use
storedSelectedRundownId and FOLLOW_LOADED_RUNDOWN_ID as before; ensure the
normalization happens inside resolveSelectedRundownId so callers/tests need no
change.

In `@apps/server/src/api-data/rundown/rundown.dao.ts`:
- Around line 619-634: getProcessedRundown currently calls
getDataProvider().getRundown(rundownId) and immediately dereferences stored
(id/title/revision) which will throw if the rundown is missing; add an explicit
null/undefined check after calling getRundown and before calling processRundown,
and if missing throw a clear error (e.g. throw new Error(`Rundown not found:
${rundownId}`)) or return an appropriate error result so callers get a helpful
message; update getProcessedRundown to only call processRundown(stored, ...) and
access stored.id/title/revision after the existence check.

---

Nitpick comments:
In `@apps/client/src/views/cuesheet/cuesheet-table/CuesheetTable.tsx`:
- Around line 228-232: The loading check uses a redundant !flatRundown
condition; since RundownSource.flatRundown is typed as ExtendedEntry[] (always
an array), simplify isLoading to only check status === 'pending' by updating the
isLoading assignment (referencing isLoading, flatRundown, and status) and keep
the existing early return to EmptyPage unchanged.

In `@apps/client/src/views/cuesheet/CuesheetTableWrapper.tsx`:
- Around line 58-68: The JSX fragment wrapping the single RundownSelect is
redundant; in CuesheetTableWrapper replace the insertElement prop value that
currently uses <>...</> with a direct JSX element (set
insertElement={<RundownSelect ... />}), keeping all props (cuesheetMode,
selectedRundownId, loadedRundownId, setSelectedRundownId, projectRundowns)
unchanged and leaving RundownSelect as the sole child.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 2526da59-bdf9-432d-8521-2af08435e251

📥 Commits

Reviewing files that changed from the base of the PR and between 9ae49a7 and b392900.

⛔ Files ignored due to path filters (1)
  • packages/types/src/api/websocket/refetch.type.ts is excluded by none and included by none
📒 Files selected for processing (32)
  • apps/client/src/common/api/rundown.ts
  • apps/client/src/common/hooks-query/useProjectRundowns.ts
  • apps/client/src/common/hooks-query/useRundown.ts
  • apps/client/src/common/hooks-query/useScopedRundown.ts
  • apps/client/src/common/hooks/useEntryAction.ts
  • apps/client/src/common/utils/socket.ts
  • apps/client/src/features/app-settings/panel/manage-panel/ManageRundowns.tsx
  • apps/client/src/features/rundown/RundownExport.tsx
  • apps/client/src/features/rundown/entry-editor/CuesheetEventEditor.tsx
  • apps/client/src/features/rundown/rundown-table/EditorTableSettings.tsx
  • apps/client/src/features/rundown/rundown-table/RundownTable.tsx
  • apps/client/src/features/rundown/useEventSelection.ts
  • apps/client/src/views/cuesheet/CuesheetPage.module.scss
  • apps/client/src/views/cuesheet/CuesheetPage.tsx
  • apps/client/src/views/cuesheet/CuesheetTableWrapper.tsx
  • apps/client/src/views/cuesheet/__tests__/useApplyCuesheetPolicy.test.ts
  • apps/client/src/views/cuesheet/__tests__/useCuesheetRundownSelection.test.ts
  • apps/client/src/views/cuesheet/cuesheet-edit-modal/EntryEditModal.tsx
  • apps/client/src/views/cuesheet/cuesheet-table/CuesheetTable.tsx
  • apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/EditableImage.tsx
  • apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-settings/CuesheetTableHeaderToolbar.tsx
  • apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-settings/CuesheetTableSettings.module.scss
  • apps/client/src/views/cuesheet/useApplyCuesheetPolicy.ts
  • apps/client/src/views/cuesheet/useCuesheetRundownSelection.ts
  • apps/server/src/api-data/rundown/__mocks__/rundown.mocks.ts
  • apps/server/src/api-data/rundown/__tests__/rundown.dao.test.ts
  • apps/server/src/api-data/rundown/rundown.dao.ts
  • apps/server/src/api-data/rundown/rundown.parser.ts
  • apps/server/src/api-data/rundown/rundown.router.ts
  • apps/server/src/api-data/rundown/rundown.service.ts
  • apps/server/src/api-data/rundown/rundown.validation.ts
  • apps/server/src/api-integration/integration.controller.ts
💤 Files with no reviewable changes (2)
  • apps/server/src/api-data/rundown/rundown.validation.ts
  • apps/client/src/features/rundown/rundown-table/EditorTableSettings.tsx

Comment on lines +73 to +75
export const useScopedEntryActions = (rundownId: string | null) => useEntryActionsForRundown(rundownId ?? '');

function useEntryActionsForRundown(scopedRundownId: string | undefined) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Preserve fallback semantics for missing scoped rundown ID.

useScopedEntryActions currently converts null to '', which forces a scoped query key for an empty ID instead of using the loaded-rundown fallback path in useEntryActionsForRundown.

Suggested fix
-export const useScopedEntryActions = (rundownId: string | null) => useEntryActionsForRundown(rundownId ?? '');
+export const useScopedEntryActions = (rundownId: string | null) =>
+  useEntryActionsForRundown(rundownId ?? undefined);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export const useScopedEntryActions = (rundownId: string | null) => useEntryActionsForRundown(rundownId ?? '');
function useEntryActionsForRundown(scopedRundownId: string | undefined) {
export const useScopedEntryActions = (rundownId: string | null) =>
useEntryActionsForRundown(rundownId ?? undefined);
function useEntryActionsForRundown(scopedRundownId: string | undefined) {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/client/src/common/hooks/useEntryAction.ts` around lines 73 - 75, The
helper useScopedEntryActions currently maps a null rundownId to an empty string
which creates an explicit scoped key and bypasses the fallback path in
useEntryActionsForRundown; update useScopedEntryActions so it forwards undefined
(e.g. pass rundownId ?? undefined or conditional if null) instead of '' and keep
the parameter types compatible with useEntryActionsForRundown
(useScopedEntryActions(rundownId: string | null) =>
useEntryActionsForRundown(rundownId ?? undefined)) so the loaded-rundown
fallback path is preserved.

Comment on lines +140 to +142
const rundownId = ontimeQueryClient.getQueryData<ProjectRundownsList>(PROJECT_RUNDOWNS)?.loaded;
if (!rundownId) return undefined;
return ontimeQueryClient.getQueryData<Rundown>(getRundownQueryKey(rundownId));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Selection range logic is pinned to the loaded rundown, which can mis-select in background tables.

Line 140 hard-codes selection data to PROJECT_RUNDOWNS.loaded. But CuesheetTable is now source-driven, so shift/ctrl range logic can compute against a different rundown than the visible one when editing/viewing a secondary rundown.

Please scope selection lookup to the active table rundown (e.g., store/set active rundownId in useEventSelection from CuesheetTable and use that ID for getRundownQueryKey(...)).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/client/src/features/rundown/useEventSelection.ts` around lines 140 -
142, The selection lookup in useEventSelection is hard-coded to
PROJECT_RUNDOWNS.loaded which can produce incorrect range selections for
background/secondary rundowns; instead accept or read an active rundownId
supplied by CuesheetTable (e.g., pass/set an active rundownId in
useEventSelection from CuesheetTable) and use that ID when calling
getRundownQueryKey(rundownId) and when computing shift/ctrl range logic; replace
usages of getQueryData<ProjectRundownsList>(PROJECT_RUNDOWNS)?.loaded with the
active rundownId parameter/state and ensure all selection computation in
useEventSelection uses that ID.

Comment thread apps/client/src/views/cuesheet/__tests__/useCuesheetRundownSelection.test.ts Outdated
return (
<Toolbar.Root className={style.tableSettings}>
<ViewSettings optionsStore={options} />
<Toolbar.Root className={style.tableSettings} data-background-rundown={!modeControls?.isCurrentRundown}>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Verify data-background-rundown attribute logic when modeControls is undefined.

When modeControls is undefined (editor context), !modeControls?.isCurrentRundown evaluates to !undefinedtrue, causing the toolbar to display the "BACKGROUND EDIT" styling. This seems unintended for the editor view.

🐛 Suggested fix
-    <Toolbar.Root className={style.tableSettings} data-background-rundown={!modeControls?.isCurrentRundown}>
+    <Toolbar.Root className={style.tableSettings} data-background-rundown={modeControls && !modeControls.isCurrentRundown}>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<Toolbar.Root className={style.tableSettings} data-background-rundown={!modeControls?.isCurrentRundown}>
<Toolbar.Root className={style.tableSettings} data-background-rundown={modeControls && !modeControls.isCurrentRundown}>
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-settings/CuesheetTableHeaderToolbar.tsx`
at line 70, The data-background-rundown attribute on Toolbar.Root is currently
set with !modeControls?.isCurrentRundown which evaluates to true when
modeControls is undefined; change the logic so the attribute is true only when
modeControls exists and isCurrentRundown is false (e.g., use modeControls ?
!modeControls.isCurrentRundown : false or Boolean(modeControls &&
!modeControls.isCurrentRundown)); update the Toolbar.Root prop (in
CuesheetTableHeaderToolbar.tsx) referencing modeControls and isCurrentRundown to
implement this explicit check so editor context doesn't show BACKGROUND EDIT
styling.

Comment thread apps/client/src/views/cuesheet/useCuesheetRundownSelection.ts Outdated
Comment thread apps/server/src/api-data/rundown/rundown.dao.ts
@alex-Arc alex-Arc force-pushed the cuesheet-rundown branch 2 times, most recently from c9d4eb0 to 86d3449 Compare May 28, 2026 07:46
@alex-Arc alex-Arc force-pushed the cuesheet-rundown branch from 86d3449 to 9d63976 Compare May 28, 2026 07:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants