diff --git a/apps/server/src/api-data/rundown/rundown.service.ts b/apps/server/src/api-data/rundown/rundown.service.ts index f86a47026..af8a65ca9 100644 --- a/apps/server/src/api-data/rundown/rundown.service.ts +++ b/apps/server/src/api-data/rundown/rundown.service.ts @@ -8,6 +8,7 @@ import { isOntimeDelay, isOntimeEvent, OntimeEntry, + OntimeEvent, PatchWithId, Rundown, } from 'ontime-types'; @@ -84,7 +85,7 @@ export async function editEntry(patch: PatchWithId): Promise { } // we dont allow the user to change the cue to empty string - if (isOntimeEvent(patch) && patch?.cue === '') { + if ((patch as Partial)?.cue === '') { throw new Error('Cue value invalid'); } @@ -107,7 +108,7 @@ export async function editEntry(patch: PatchWithId): Promise { updateRuntimeOnChange(rundownMetadata); // notify timer and external services of change - notifyChanges(rundownMetadata, revision, { timer: [entry.id], external: true }); + notifyChanges(rundownMetadata, revision, { timer: didInvalidate ? true : [entry.id], external: true }); }); return entry; @@ -171,7 +172,7 @@ export async function batchEditEntries(ids: EntryId[], patch: Partial id === runtimeState.eventNow?.id); + loadNow(timedEvents, eventNowIndex >= 0 ? eventNowIndex : undefined); + loadNext(timedEvents, eventNowIndex >= 0 ? eventNowIndex : undefined); updateLoaded(runtimeState.eventNow ?? undefined); loadBlock(rundown); } diff --git a/e2e/tests/features/213-arrange-while-playing.spec.ts b/e2e/tests/features/213-arrange-while-playing.spec.ts new file mode 100644 index 000000000..1c85fa791 --- /dev/null +++ b/e2e/tests/features/213-arrange-while-playing.spec.ts @@ -0,0 +1,27 @@ +import { test, expect } from '@playwright/test'; + +test('Rearrange while playing', async ({ page }) => { + await page.goto('http://localhost:4001/rundown'); + + // clear rundown + await page.getByRole('button', { name: 'Clear rundown' }).click(); + await page.getByRole('button', { name: 'Delete all' }).click(); + + // create events + await page.getByRole('button', { name: 'Create Event' }).click(); + await page.getByRole('button', { name: 'Event' }).nth(4).click(); + await page.getByRole('button', { name: 'Event', exact: true }).nth(1).click(); + + // start event 2 + await page.getByTestId('entry-2').getByRole('button', { name: 'Start event' }).click(); + await expect(page.getByTestId('entry-2').locator('#event-block')).toHaveCSS('background-color', 'rgb(8, 122, 39)'); + + // move event 2 up + await page.getByTestId('entry-2').locator('#event-block').getByText('2').click(); + await page.getByTestId('entry-2').locator('#event-block div').filter({ hasText: '2' }).press('Alt+Control+ArrowUp'); + + // event CUE1 should new be entry 2 + await expect(page.getByTestId('entry-2').locator('#event-block')).toContainText('1'); + // but entry 1 should be the one playing (it will be unlinked as it will be the first event) + await expect(page.getByTestId('entry-1').locator('#event-block')).toHaveCSS('background-color', 'rgb(8, 122, 39)'); +});