mirror of
https://github.com/cpvalente/ontime.git
synced 2026-09-11 17:19:34 +00:00
fix: prevent nesting groups
This commit is contained in:
committed by
Carlos Valente
parent
9ab54edbf5
commit
524721002a
@@ -693,6 +693,7 @@ export const useEntryActions = () => {
|
|||||||
await reorderEntryMutation(reorderObject);
|
await reorderEntryMutation(reorderObject);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logAxiosError('Error re-ordering event', error);
|
logAxiosError('Error re-ordering event', error);
|
||||||
|
throw error; // rethrow to handle in the component
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[reorderEntryMutation],
|
[reorderEntryMutation],
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ import QuickAddButtons from './entry-editor/quick-add-buttons/QuickAddButtons';
|
|||||||
import QuickAddInline from './entry-editor/quick-add-cursor/QuickAddInline';
|
import QuickAddInline from './entry-editor/quick-add-cursor/QuickAddInline';
|
||||||
import BlockEnd from './rundown-block/BlockEnd';
|
import BlockEnd from './rundown-block/BlockEnd';
|
||||||
import RundownBlock from './rundown-block/RundownBlock';
|
import RundownBlock from './rundown-block/RundownBlock';
|
||||||
import { makeRundownMetadata, makeSortableList } from './rundown.utils';
|
import { canDrop, makeRundownMetadata, makeSortableList } from './rundown.utils';
|
||||||
import RundownEmpty from './RundownEmpty';
|
import RundownEmpty from './RundownEmpty';
|
||||||
import { useEventSelection } from './useEventSelection';
|
import { useEventSelection } from './useEventSelection';
|
||||||
|
|
||||||
@@ -335,14 +335,14 @@ export default function Rundown({ data }: RundownProps) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// prevent dropping a group inside another
|
||||||
|
if (active.data.current?.type === 'block' && !canDrop(over.data.current?.type, over.data.current?.parent)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const fromIndex = active.data.current?.sortable.index;
|
const fromIndex = active.data.current?.sortable.index;
|
||||||
const toIndex = over.data.current?.sortable.index;
|
const toIndex = over.data.current?.sortable.index;
|
||||||
|
|
||||||
// we keep a copy of the state as a hack to handle inconsistencies between dnd-kit and async store updates
|
|
||||||
setSortableData((currentEntries) => {
|
|
||||||
return reorderArray(currentEntries, fromIndex, toIndex);
|
|
||||||
});
|
|
||||||
|
|
||||||
let destinationId = over.id as EntryId;
|
let destinationId = over.id as EntryId;
|
||||||
let order: 'before' | 'after' | 'insert' = fromIndex < toIndex ? 'after' : 'before';
|
let order: 'before' | 'after' | 'insert' = fromIndex < toIndex ? 'after' : 'before';
|
||||||
|
|
||||||
@@ -368,7 +368,16 @@ export default function Rundown({ data }: RundownProps) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
reorderEntry(active.id as EntryId, destinationId, order);
|
|
||||||
|
// keep copy of the current state in case we need to revert
|
||||||
|
const currentEntries = structuredClone(sortableData);
|
||||||
|
// we keep a copy of the state as a hack to handle inconsistencies between dnd-kit and async store updates
|
||||||
|
setSortableData((currentEntries) => {
|
||||||
|
return reorderArray(currentEntries, fromIndex, toIndex);
|
||||||
|
});
|
||||||
|
reorderEntry(active.id as EntryId, destinationId, order).catch((_) => {
|
||||||
|
setSortableData(currentEntries);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -17,6 +17,9 @@ export default function BlockEnd({ id, colour }: BlockEndProps) {
|
|||||||
transition,
|
transition,
|
||||||
} = useSortable({
|
} = useSortable({
|
||||||
id,
|
id,
|
||||||
|
data: {
|
||||||
|
type: 'end-block',
|
||||||
|
},
|
||||||
animateLayoutChanges: () => false,
|
animateLayoutChanges: () => false,
|
||||||
disabled: true, // we do not want to drag end blocks
|
disabled: true, // we do not want to drag end blocks
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -158,15 +158,21 @@ export function makeSortableList(order: EntryId[], entries: RundownEntries): Ent
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether a drop operation is valid
|
* Checks whether a drop operation is valid
|
||||||
* Currently only used for validating dropping blocks
|
* Currently only used for validating dropping groups
|
||||||
*/
|
*/
|
||||||
export function canDrop(targetType?: SupportedEntry, targetParent?: EntryId | null): boolean {
|
export function canDrop(targetType?: SupportedEntry & 'end-block', targetParent?: EntryId | null): boolean {
|
||||||
if (targetType === 'event' || targetType === 'delay') {
|
// this would mean inserting a group inside another
|
||||||
return targetParent === null;
|
if (targetType === 'end-block') {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
// remaining events will be block or end-block
|
|
||||||
// we can swap places with other blocks
|
// this means swapping places with another group
|
||||||
return targetType == 'block';
|
if (targetType === 'block') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// for all other cases, we just need to check if we are inside a group
|
||||||
|
return targetParent === null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user