From 3790681becd478206cd1947a026b81208b5c0f7a Mon Sep 17 00:00:00 2001 From: Carlos Valente Date: Fri, 4 Jul 2025 21:42:18 +0200 Subject: [PATCH] fix: reordering out of a block --- .../rundown/__tests__/rundown.utils.test.ts | 2 +- .../src/features/rundown/rundown.utils.ts | 19 +++++++----- .../rundown/__tests__/rundown.dao.test.ts | 31 ++++++++++++++++++- .../src/api-data/rundown/rundown.dao.ts | 13 ++++++-- .../src/api-data/rundown/rundown.service.ts | 1 + 5 files changed, 54 insertions(+), 12 deletions(-) diff --git a/apps/client/src/features/rundown/__tests__/rundown.utils.test.ts b/apps/client/src/features/rundown/__tests__/rundown.utils.test.ts index ca54128d8..945686585 100644 --- a/apps/client/src/features/rundown/__tests__/rundown.utils.test.ts +++ b/apps/client/src/features/rundown/__tests__/rundown.utils.test.ts @@ -480,7 +480,7 @@ describe('moveDown()', () => { it('moves an entry down out of a group', () => { expect(moveDown('12', rundown.flatOrder, rundown.entries)).toStrictEqual({ - destinationId: '4', + destinationId: 'block', order: 'after', }); }); diff --git a/apps/client/src/features/rundown/rundown.utils.ts b/apps/client/src/features/rundown/rundown.utils.ts index e704b4518..080f8cf80 100644 --- a/apps/client/src/features/rundown/rundown.utils.ts +++ b/apps/client/src/features/rundown/rundown.utils.ts @@ -244,17 +244,20 @@ export function moveDown( const currentIndex = flatOrder.indexOf(entryId); const nextEntryId = flatOrder[currentIndex + 1]; - // 1. moving at the top of the list - if (!nextEntryId) { - // 1a. we are in a block and need to move outside of it - if ('parent' in currentEntry && currentEntry.parent !== null) { + // 1. check if we're the last entry in a block + if ('parent' in currentEntry && currentEntry.parent !== null) { + const parentBlock = entries[currentEntry.parent]; + if (isOntimeBlock(parentBlock) && parentBlock.entries[parentBlock.entries.length - 1] === entryId) { return { destinationId: currentEntry.parent, order: 'after' }; } - // 1b. we are at the end of the rundown, no movement possible + } + + // 2. moving at the end of the list + if (!nextEntryId) { return { destinationId: null, order: 'after' }; } - // 2. moving a block (always moves at top level) + // 3. moving a block (always moves at top level) if (isOntimeBlock(currentEntry)) { // if next entry is inside this block, skip past all children if (currentEntry.entries.includes(nextEntryId)) { @@ -275,7 +278,7 @@ export function moveDown( const nextEntry = entries[nextEntryId]; const currentEntryParent = currentEntry.parent; - // 3. handle moving relative to blocks + // 4. handle moving relative to blocks if (isOntimeBlock(nextEntry)) { if (currentEntryParent === null) { // we are entering a block @@ -289,7 +292,7 @@ export function moveDown( } } - // 4. handle moving between block and top level + // 5. handle moving between block and top level const nextEntryParent = isOntimeEvent(nextEntry) ? nextEntry.parent : null; if (nextEntryParent !== null && currentEntryParent === null) { return { destinationId: nextEntryId, order: 'after' }; diff --git a/apps/server/src/api-data/rundown/__tests__/rundown.dao.test.ts b/apps/server/src/api-data/rundown/__tests__/rundown.dao.test.ts index c75befd09..3c0b17e92 100644 --- a/apps/server/src/api-data/rundown/__tests__/rundown.dao.test.ts +++ b/apps/server/src/api-data/rundown/__tests__/rundown.dao.test.ts @@ -926,7 +926,7 @@ describe('rundownMutation.reorder()', () => { expect(rundown.order).toStrictEqual(['3', '1', '2']); }); - it('moves an event out of a block', () => { + it('moves an event out and before a block', () => { const rundown = makeRundown({ order: ['1', '2'], flatOrder: ['1', '11', '2'], @@ -943,6 +943,35 @@ describe('rundownMutation.reorder()', () => { expect(rundown.entries['1']).toMatchObject({ entries: [], }); + expect(rundown.entries['11']).toMatchObject({ + parent: null, + }); + expect(rundown.entries['2']).toMatchObject({ + parent: null, + }); + }); + + it('moves an event out and after a block', () => { + const rundown = makeRundown({ + order: ['1', 'block', '2'], + flatOrder: ['1', 'block', '11', '2'], + entries: { + '1': makeOntimeEvent({ id: '1', parent: null }), + block: makeOntimeBlock({ id: 'block', entries: ['11'] }), + '11': makeOntimeEvent({ id: '11', parent: 'block' }), + '2': makeOntimeEvent({ id: '2', parent: null }), + }, + }); + + rundownMutation.reorder(rundown, rundown.entries['11'], rundown.entries['block'], 'after'); + + expect(rundown.order).toStrictEqual(['1', 'block', '11', '2']); + expect(rundown.entries['block']).toMatchObject({ + entries: [], + }); + expect(rundown.entries['11']).toMatchObject({ + parent: null, + }); expect(rundown.entries['2']).toMatchObject({ parent: null, }); diff --git a/apps/server/src/api-data/rundown/rundown.dao.ts b/apps/server/src/api-data/rundown/rundown.dao.ts index a7209247f..96e10aa02 100644 --- a/apps/server/src/api-data/rundown/rundown.dao.ts +++ b/apps/server/src/api-data/rundown/rundown.dao.ts @@ -289,6 +289,10 @@ function reorder(rundown: Rundown, eventFrom: OntimeEntry, eventTo: OntimeEntry, const fromParent: EntryId | null = (eventFrom as { parent?: EntryId })?.parent ?? null; const toParent = (() => { if (isOntimeBlock(eventTo)) { + // Special case: if we're moving relative to our own parent block, remove from block + if ('parent' in eventFrom && eventFrom.parent === eventTo.id) { + return null; + } if (order === 'insert') { // prevent blocks from being inserted into other blocks if (isOntimeBlock(eventFrom)) { @@ -313,8 +317,13 @@ function reorder(rundown: Rundown, eventFrom: OntimeEntry, eventTo: OntimeEntry, const toIndex = (() => { const baseIndex = destinationArray.indexOf(eventTo.id); if (order === 'before') return baseIndex; - // only add one if we are moving down - if (order === 'after') return baseIndex + (fromIndex < baseIndex ? 0 : 1); + if (order === 'after') { + // When moving within the same array, we need to consider the source position + if (sourceArray === destinationArray && fromIndex <= baseIndex) { + return baseIndex; + } + return baseIndex + 1; + } // for insert we add in the end of the array return destinationArray.length; })(); diff --git a/apps/server/src/api-data/rundown/rundown.service.ts b/apps/server/src/api-data/rundown/rundown.service.ts index 3872a8b2b..991cc09f8 100644 --- a/apps/server/src/api-data/rundown/rundown.service.ts +++ b/apps/server/src/api-data/rundown/rundown.service.ts @@ -247,6 +247,7 @@ export function reorderEntry(entryId: EntryId, destinationId: EntryId, order: 'b throw new Error('Event not found'); } + console.log('reorder', eventFrom.id, eventTo.id, order); rundownMutation.reorder(rundown, eventFrom, eventTo, order); const { rundown: rundownResult, rundownMetadata, revision } = commit();