feat: Implement undo and redo functionality for 2D scene controls

- Added useRedoHandler to manage redo actions, including socket communication for wall, floor, zone, and aisle updates.
- Added useUndoHandler to manage undo actions, reversing the effects of previous actions with corresponding socket updates.
- Created UndoRedo2DControls component to handle keyboard shortcuts for undo (Ctrl+Z) and redo (Ctrl+Y).
- Established a Zustand store (useUndoRedo2DStore) to maintain undo and redo stacks, with methods for pushing, popping, and peeking actions.
This commit is contained in:
2025-07-29 17:20:34 +05:30
parent 253b3db2ed
commit fcd924eb31
15 changed files with 1701 additions and 301 deletions

View File

@@ -7,6 +7,8 @@ import { createAisleStore, AisleStoreType } from '../../store/builder/useAisleSt
import { createZoneStore, ZoneStoreType } from '../../store/builder/useZoneStore';
import { createFloorStore, FloorStoreType } from '../../store/builder/useFloorStore';
import { createUndoRedo2DStore, UndoRedo2DStoreType } from '../../store/builder/useUndoRedo2DStore';
import { createEventStore, EventStoreType } from '../../store/simulation/useEventsStore';
import { createProductStore, ProductStoreType } from '../../store/simulation/useProductStore';
@@ -27,6 +29,8 @@ type SceneContextValue = {
zoneStore: ZoneStoreType,
floorStore: FloorStoreType,
undoRedo2DStore: UndoRedo2DStoreType,
eventStore: EventStoreType,
productStore: ProductStoreType,
@@ -62,6 +66,8 @@ export function SceneProvider({
const zoneStore = useMemo(() => createZoneStore(), []);
const floorStore = useMemo(() => createFloorStore(), []);
const undoRedo2DStore = useMemo(() => createUndoRedo2DStore(), []);
const eventStore = useMemo(() => createEventStore(), []);
const productStore = useMemo(() => createProductStore(), []);
@@ -82,6 +88,7 @@ export function SceneProvider({
aisleStore.getState().clearAisles();
zoneStore.getState().clearZones();
floorStore.getState().clearFloors();
undoRedo2DStore.getState().clearUndoRedo2D();
eventStore.getState().clearEvents();
productStore.getState().clearProducts();
materialStore.getState().clearMaterials();
@@ -92,7 +99,7 @@ export function SceneProvider({
storageUnitStore.getState().clearStorageUnits();
humanStore.getState().clearHumans();
humanEventManagerRef.current.humanStates = [];
}, [assetStore, wallAssetStore, wallStore, aisleStore, zoneStore, floorStore, eventStore, productStore, materialStore, armBotStore, machineStore, conveyorStore, vehicleStore, storageUnitStore, humanStore]);
}, [assetStore, wallAssetStore, wallStore, aisleStore, zoneStore, undoRedo2DStore, floorStore, eventStore, productStore, materialStore, armBotStore, machineStore, conveyorStore, vehicleStore, storageUnitStore, humanStore]);
const contextValue = useMemo(() => (
{
@@ -102,6 +109,7 @@ export function SceneProvider({
aisleStore,
zoneStore,
floorStore,
undoRedo2DStore,
eventStore,
productStore,
materialStore,
@@ -115,7 +123,7 @@ export function SceneProvider({
clearStores,
layout
}
), [assetStore, wallAssetStore, wallStore, aisleStore, zoneStore, floorStore, eventStore, productStore, materialStore, armBotStore, machineStore, conveyorStore, vehicleStore, storageUnitStore, humanStore, clearStores, layout]);
), [assetStore, wallAssetStore, wallStore, aisleStore, zoneStore, floorStore, undoRedo2DStore, eventStore, productStore, materialStore, armBotStore, machineStore, conveyorStore, vehicleStore, storageUnitStore, humanStore, clearStores, layout]);
return (
<SceneContext.Provider value={contextValue}>