feat: Implement Zustand stores for machine, simulation, storage unit, vehicle, and visualization management

- Added `useMachineStore` for managing machine statuses, including actions for adding, removing, and updating machines.
- Introduced `useSimulationStore` to handle product and event management with actions for adding, removing, and updating products and events.
- Created `useStorageUnitStore` for managing storage unit statuses, including load tracking and state updates.
- Developed `useVehicleStore` for vehicle management, including load and state updates.
- Implemented `useChartStore` for managing measurement data and visualization settings.
- Added `useDroppedObjectsStore` for handling dropped objects in visualization zones, including object manipulation actions.
- Created `useZone3DWidgetStore` for managing 3D widget data in zones, including position and rotation updates.
- Introduced `useZoneStore` for managing selected zone states and widget configurations.
This commit is contained in:
2025-04-22 14:28:29 +05:30
parent 78b9663d0f
commit 6363d5b9af
65 changed files with 1306 additions and 194 deletions

View File

@@ -0,0 +1,172 @@
import { create } from 'zustand';
import { immer } from 'zustand/middleware/immer';
interface ArmBotStatus extends RoboticArmSchemaEvent {
productId: string;
isActive: boolean;
idleTime: number;
activeTime: number;
currentAction?: {
actionUuid: string;
actionName: string;
};
}
interface ArmBotStore {
armBots: Record<string, ArmBotStatus>;
// ArmBot actions
addArmBot: (productId: string, event: RoboticArmSchemaEvent) => void;
removeArmBot: (modelUuid: string) => void;
updateArmBot: (
modelUuid: string,
updates: Partial<Omit<ArmBotStatus, 'modelUuid' | 'productId'>>
) => void;
// Action management
startAction: (modelUuid: string, actionUuid: string) => void;
completeAction: (modelUuid: string) => void;
cancelAction: (modelUuid: string) => void;
// Status updates
setArmBotActive: (modelUuid: string, isActive: boolean) => void;
// Time tracking
incrementActiveTime: (modelUuid: string, incrementBy: number) => void;
incrementIdleTime: (modelUuid: string, incrementBy: number) => void;
// Helper functions
getArmBotById: (modelUuid: string) => ArmBotStatus | undefined;
getArmBotsByProduct: (productId: string) => ArmBotStatus[];
getActiveArmBots: () => ArmBotStatus[];
getIdleArmBots: () => ArmBotStatus[];
getArmBotsByCurrentAction: (actionUuid: string) => ArmBotStatus[];
}
export const useArmBotStore = create<ArmBotStore>()(
immer((set, get) => ({
armBots: {},
// ArmBot actions
addArmBot: (productId, event) => {
set((state) => {
state.armBots[event.modelUuid] = {
...event,
productId,
isActive: false,
idleTime: 0,
activeTime: 0,
state: 'idle'
};
});
},
removeArmBot: (modelUuid) => {
set((state) => {
delete state.armBots[modelUuid];
});
},
updateArmBot: (modelUuid, updates) => {
set((state) => {
const armBot = state.armBots[modelUuid];
if (armBot) {
Object.assign(armBot, updates);
}
});
},
// Action management
startAction: (modelUuid, actionUuid) => {
set((state) => {
const armBot = state.armBots[modelUuid];
if (armBot) {
const action = armBot.point.actions.find(a => a.actionUuid === actionUuid);
if (action) {
armBot.currentAction = {
actionUuid: action.actionUuid,
actionName: action.actionName
};
armBot.isActive = true;
}
}
});
},
completeAction: (modelUuid) => {
set((state) => {
const armBot = state.armBots[modelUuid];
if (armBot && armBot.currentAction) {
armBot.currentAction = undefined;
armBot.isActive = false;
}
});
},
cancelAction: (modelUuid) => {
set((state) => {
const armBot = state.armBots[modelUuid];
if (armBot) {
armBot.currentAction = undefined;
armBot.isActive = false;
}
});
},
// Status updates
setArmBotActive: (modelUuid, isActive) => {
set((state) => {
const armBot = state.armBots[modelUuid];
if (armBot) {
armBot.isActive = isActive;
}
});
},
// Time tracking
incrementActiveTime: (modelUuid, incrementBy) => {
set((state) => {
const armBot = state.armBots[modelUuid];
if (armBot) {
armBot.activeTime += incrementBy;
}
});
},
incrementIdleTime: (modelUuid, incrementBy) => {
set((state) => {
const armBot = state.armBots[modelUuid];
if (armBot) {
armBot.idleTime += incrementBy;
}
});
},
// Helper functions
getArmBotById: (modelUuid) => {
return get().armBots[modelUuid];
},
getArmBotsByProduct: (productId) => {
return Object.values(get().armBots).filter(
a => a.productId === productId
);
},
getActiveArmBots: () => {
return Object.values(get().armBots).filter(a => a.isActive);
},
getIdleArmBots: () => {
return Object.values(get().armBots).filter(
a => !a.isActive && a.state === 'idle'
);
},
getArmBotsByCurrentAction: (actionUuid) => {
return Object.values(get().armBots).filter(
a => a.currentAction?.actionUuid === actionUuid
);
}
}))
);

View File

@@ -0,0 +1,129 @@
import { create } from 'zustand';
import { immer } from 'zustand/middleware/immer';
interface ConveyorStatus extends ConveyorEventSchema {
productId: string;
isActive: boolean;
idleTime: number;
activeTime: number;
}
interface ConveyorStore {
conveyors: Record<string, ConveyorStatus>;
// Actions
addConveyor: (productId: string, event: ConveyorEventSchema) => void;
removeConveyor: (modelUuid: string) => void;
updateConveyor: (
modelUuid: string,
updates: Partial<Omit<ConveyorStatus, 'modelUuid' | 'productId'>>
) => void;
// Status updates
setConveyorActive: (modelUuid: string, isActive: boolean) => void;
setConveyorState: (modelUuid: string, newState: ConveyorStatus['state']) => void;
// Time tracking
incrementActiveTime: (modelUuid: string, incrementBy: number) => void;
incrementIdleTime: (modelUuid: string, incrementBy: number) => void;
// Helper functions
getConveyorById: (modelUuid: string) => ConveyorStatus | undefined;
getConveyorsByProduct: (productId: string) => ConveyorStatus[];
getActiveConveyors: () => ConveyorStatus[];
getIdleConveyors: () => ConveyorStatus[];
}
export const useConveyorStore = create<ConveyorStore>()(
immer((set, get) => ({
conveyors: {},
// Actions
addConveyor: (productId, event) => {
set((state) => {
state.conveyors[event.modelUuid] = {
...event,
productId,
isActive: false,
idleTime: 0,
activeTime: 0,
state: 'idle',
};
});
},
removeConveyor: (modelUuid) => {
set((state) => {
delete state.conveyors[modelUuid];
});
},
updateConveyor: (modelUuid, updates) => {
set((state) => {
const conveyor = state.conveyors[modelUuid];
if (conveyor) {
Object.assign(conveyor, updates);
}
});
},
// Status updates
setConveyorActive: (modelUuid, isActive) => {
set((state) => {
const conveyor = state.conveyors[modelUuid];
if (conveyor) {
conveyor.isActive = isActive;
}
});
},
setConveyorState: (modelUuid, newState) => {
set((state) => {
const conveyor = state.conveyors[modelUuid];
if (conveyor) {
conveyor.state = newState;
}
});
},
// Time tracking
incrementActiveTime: (modelUuid, incrementBy) => {
set((state) => {
const conveyor = state.conveyors[modelUuid];
if (conveyor) {
conveyor.activeTime += incrementBy;
}
});
},
incrementIdleTime: (modelUuid, incrementBy) => {
set((state) => {
const conveyor = state.conveyors[modelUuid];
if (conveyor) {
conveyor.idleTime += incrementBy;
}
});
},
// Helper functions
getConveyorById: (modelUuid) => {
return get().conveyors[modelUuid];
},
getConveyorsByProduct: (productId) => {
return Object.values(get().conveyors).filter(
c => c.productId === productId
);
},
getActiveConveyors: () => {
return Object.values(get().conveyors).filter(c => c.isActive);
},
getIdleConveyors: () => {
return Object.values(get().conveyors).filter(
c => !c.isActive && c.state === 'idle'
);
},
}))
);

View File

@@ -1,37 +1,33 @@
import { create } from 'zustand';
import { immer } from 'zustand/middleware/immer';
import { useProductStore } from './useSimulationStore';
type EventsStore = {
events: EventsSchema[];
// Sync with product store
syncFromProducts: (products: productsSchema) => void;
// Event-level actions
addEvent: (event: EventsSchema) => void;
removeEvent: (modelUuid: string) => void;
updateEvent: (modelUuid: string, updates: Partial<EventsSchema>) => void;
// Point-level actions
addPoint: (modelUuid: string, point: TransferPointSchema | VehiclePointSchema | RoboticArmPointSchema | MachinePointSchema | StoragePointSchema) => void;
addPoint: (modelUuid: string, point: ConveyorPointSchema | VehiclePointSchema | RoboticArmPointSchema | MachinePointSchema | StoragePointSchema) => void;
removePoint: (modelUuid: string, pointUuid: string) => void;
updatePoint: (
modelUuid: string,
pointUuid: string,
updates: Partial<TransferPointSchema | VehiclePointSchema | RoboticArmPointSchema | MachinePointSchema | StoragePointSchema>
updates: Partial<ConveyorPointSchema | VehiclePointSchema | RoboticArmPointSchema | MachinePointSchema | StoragePointSchema>
) => void;
// Action-level actions
addAction: (
modelUuid: string,
pointUuid: string,
action: TransferPointSchema['action'] | VehiclePointSchema['action'] | RoboticArmPointSchema['actions'][0] | MachinePointSchema['action'] | StoragePointSchema['action']
action: ConveyorPointSchema['action'] | VehiclePointSchema['action'] | RoboticArmPointSchema['actions'][0] | MachinePointSchema['action'] | StoragePointSchema['action']
) => void;
removeAction: (actionUuid: string) => void;
updateAction: (
actionUuid: string,
updates: Partial<TransferPointSchema['action'] | VehiclePointSchema['action'] | RoboticArmPointSchema['actions'][0] | MachinePointSchema['action'] | StoragePointSchema['action']>
updates: Partial<ConveyorPointSchema['action'] | VehiclePointSchema['action'] | RoboticArmPointSchema['actions'][0] | MachinePointSchema['action'] | StoragePointSchema['action']>
) => void;
// Trigger-level actions
@@ -41,8 +37,8 @@ type EventsStore = {
// Helper functions
getEventByModelUuid: (modelUuid: string) => EventsSchema | undefined;
getPointByUuid: (modelUuid: string, pointUuid: string) => TransferPointSchema | VehiclePointSchema | RoboticArmPointSchema | MachinePointSchema | StoragePointSchema | undefined;
getActionByUuid: (actionUuid: string) => (TransferPointSchema['action'] | VehiclePointSchema['action'] | RoboticArmPointSchema['actions'][0] | MachinePointSchema['action'] | StoragePointSchema['action']) | undefined;
getPointByUuid: (modelUuid: string, pointUuid: string) => ConveyorPointSchema | VehiclePointSchema | RoboticArmPointSchema | MachinePointSchema | StoragePointSchema | undefined;
getActionByUuid: (actionUuid: string) => (ConveyorPointSchema['action'] | VehiclePointSchema['action'] | RoboticArmPointSchema['actions'][0] | MachinePointSchema['action'] | StoragePointSchema['action']) | undefined;
getTriggerByUuid: (triggerUuid: string) => TriggerSchema | undefined;
};
@@ -50,13 +46,6 @@ export const useEventsStore = create<EventsStore>()(
immer((set, get) => ({
events: [],
// Sync events from products store
syncFromProducts: (products) => {
set((state) => {
state.events = products.flatMap(product => product.eventsData);
});
},
// Event-level actions
addEvent: (event) => {
set((state) => {
@@ -84,7 +73,7 @@ export const useEventsStore = create<EventsStore>()(
set((state) => {
const event = state.events.find(e => 'modelUuid' in e && e.modelUuid === modelUuid);
if (event && 'points' in event) {
(event as TransferEventSchema).points.push(point as TransferPointSchema);
(event as ConveyorEventSchema).points.push(point as ConveyorPointSchema);
} else if (event && 'point' in event) {
(event as VehicleSchemaEvent | RoboticArmSchemaEvent | MachineSchemaEvent | StorageSchemaEvent).point = point as any;
}
@@ -95,7 +84,7 @@ export const useEventsStore = create<EventsStore>()(
set((state) => {
const event = state.events.find(e => 'modelUuid' in e && e.modelUuid === modelUuid);
if (event && 'points' in event) {
(event as TransferEventSchema).points = (event as TransferEventSchema).points.filter(p => p.uuid !== pointUuid);
(event as ConveyorEventSchema).points = (event as ConveyorEventSchema).points.filter(p => p.uuid !== pointUuid);
}
// For single-point events, you might want to handle differently
});
@@ -105,7 +94,7 @@ export const useEventsStore = create<EventsStore>()(
set((state) => {
const event = state.events.find(e => 'modelUuid' in e && e.modelUuid === modelUuid);
if (event && 'points' in event) {
const point = (event as TransferEventSchema).points.find(p => p.uuid === pointUuid);
const point = (event as ConveyorEventSchema).points.find(p => p.uuid === pointUuid);
if (point) {
Object.assign(point, updates);
}
@@ -120,7 +109,7 @@ export const useEventsStore = create<EventsStore>()(
set((state) => {
const event = state.events.find(e => 'modelUuid' in e && e.modelUuid === modelUuid);
if (event && 'points' in event) {
const point = (event as TransferEventSchema).points.find(p => p.uuid === pointUuid);
const point = (event as ConveyorEventSchema).points.find(p => p.uuid === pointUuid);
if (point) {
point.action = action as any;
}
@@ -138,7 +127,7 @@ export const useEventsStore = create<EventsStore>()(
set((state) => {
for (const event of state.events) {
if ('points' in event) {
for (const point of (event as TransferEventSchema).points) {
for (const point of (event as ConveyorEventSchema).points) {
if (point.action && point.action.actionUuid === actionUuid) {
// Handle removal for single action points
}
@@ -161,7 +150,7 @@ export const useEventsStore = create<EventsStore>()(
set((state) => {
for (const event of state.events) {
if ('points' in event) {
for (const point of (event as TransferEventSchema).points) {
for (const point of (event as ConveyorEventSchema).points) {
if (point.action && point.action.actionUuid === actionUuid) {
Object.assign(point.action, updates);
return;
@@ -189,7 +178,7 @@ export const useEventsStore = create<EventsStore>()(
set((state) => {
for (const event of state.events) {
if ('points' in event) {
for (const point of (event as TransferEventSchema).points) {
for (const point of (event as ConveyorEventSchema).points) {
if (point.action && point.action.actionUuid === actionUuid) {
point.action.triggers.push(trigger);
return;
@@ -216,7 +205,7 @@ export const useEventsStore = create<EventsStore>()(
set((state) => {
for (const event of state.events) {
if ('points' in event) {
for (const point of (event as TransferEventSchema).points) {
for (const point of (event as ConveyorEventSchema).points) {
if (point.action && 'triggers' in point.action) {
point.action.triggers = point.action.triggers.filter(t => t.triggerUuid !== triggerUuid);
}
@@ -241,7 +230,7 @@ export const useEventsStore = create<EventsStore>()(
set((state) => {
for (const event of state.events) {
if ('points' in event) {
for (const point of (event as TransferEventSchema).points) {
for (const point of (event as ConveyorEventSchema).points) {
if (point.action && 'triggers' in point.action) {
const trigger = point.action.triggers.find(t => t.triggerUuid === triggerUuid);
if (trigger) {
@@ -282,7 +271,7 @@ export const useEventsStore = create<EventsStore>()(
getPointByUuid: (modelUuid, pointUuid) => {
const event = get().events.find(e => 'modelUuid' in e && e.modelUuid === modelUuid);
if (event && 'points' in event) {
return (event as TransferEventSchema).points.find(p => p.uuid === pointUuid);
return (event as ConveyorEventSchema).points.find(p => p.uuid === pointUuid);
} else if (event && 'point' in event && (event as any).point.uuid === pointUuid) {
return (event as any).point;
}
@@ -293,7 +282,7 @@ export const useEventsStore = create<EventsStore>()(
const state = get();
for (const event of state.events) {
if ('points' in event) {
for (const point of (event as TransferEventSchema).points) {
for (const point of (event as ConveyorEventSchema).points) {
if (point.action && point.action.actionUuid === actionUuid) {
return point.action;
}
@@ -315,7 +304,7 @@ export const useEventsStore = create<EventsStore>()(
const state = get();
for (const event of state.events) {
if ('points' in event) {
for (const point of (event as TransferEventSchema).points) {
for (const point of (event as ConveyorEventSchema).points) {
if (point.action && 'triggers' in point.action) {
const trigger = point.action.triggers.find(t => t.triggerUuid === triggerUuid);
if (trigger) return trigger;
@@ -340,10 +329,3 @@ export const useEventsStore = create<EventsStore>()(
}
}))
);
// Set up automatic syncing between stores
useProductStore.subscribe(
(state) => {
useEventsStore.getState().syncFromProducts(state.products);
}
);

View File

@@ -0,0 +1,129 @@
import { create } from 'zustand';
import { immer } from 'zustand/middleware/immer';
interface MachineStatus extends MachineSchemaEvent {
productId: string;
isActive: boolean;
idleTime: number;
activeTime: number;
}
interface MachineStore {
machines: Record<string, MachineStatus>;
// Actions
addMachine: (productId: string, machine: MachineSchemaEvent) => void;
removeMachine: (modelUuid: string) => void;
updateMachine: (
modelUuid: string,
updates: Partial<Omit<MachineStatus, 'modelUuid' | 'productId'>>
) => void;
// Status updates
setMachineActive: (modelUuid: string, isActive: boolean) => void;
setMachineState: (modelUuid: string, newState: MachineStatus['state']) => void;
// Time tracking
incrementActiveTime: (modelUuid: string, incrementBy: number) => void;
incrementIdleTime: (modelUuid: string, incrementBy: number) => void;
// Helpers
getMachineById: (modelUuid: string) => MachineStatus | undefined;
getMachinesByProduct: (productId: string) => MachineStatus[];
getActiveMachines: () => MachineStatus[];
getIdleMachines: () => MachineStatus[];
}
export const useMachineStore = create<MachineStore>()(
immer((set, get) => ({
machines: {},
// Actions
addMachine: (productId, machine) => {
set((state) => {
state.machines[machine.modelUuid] = {
...machine,
productId,
isActive: false,
idleTime: 0,
activeTime: 0,
state: 'idle',
};
});
},
removeMachine: (modelUuid) => {
set((state) => {
delete state.machines[modelUuid];
});
},
updateMachine: (modelUuid, updates) => {
set((state) => {
const machine = state.machines[modelUuid];
if (machine) {
Object.assign(machine, updates);
}
});
},
// Status updates
setMachineActive: (modelUuid, isActive) => {
set((state) => {
const machine = state.machines[modelUuid];
if (machine) {
machine.isActive = isActive;
}
});
},
setMachineState: (modelUuid, newState) => {
set((state) => {
const machine = state.machines[modelUuid];
if (machine) {
machine.state = newState;
}
});
},
// Time tracking
incrementActiveTime: (modelUuid, incrementBy) => {
set((state) => {
const machine = state.machines[modelUuid];
if (machine) {
machine.activeTime += incrementBy;
}
});
},
incrementIdleTime: (modelUuid, incrementBy) => {
set((state) => {
const machine = state.machines[modelUuid];
if (machine) {
machine.idleTime += incrementBy;
}
});
},
// Helpers
getMachineById: (modelUuid) => {
return get().machines[modelUuid];
},
getMachinesByProduct: (productId) => {
return Object.values(get().machines).filter(
m => m.productId === productId
);
},
getActiveMachines: () => {
return Object.values(get().machines).filter(m => m.isActive);
},
getIdleMachines: () => {
return Object.values(get().machines).filter(
m => !m.isActive && m.state === 'idle'
);
},
}))
);

View File

@@ -1,7 +1,7 @@
import { create } from 'zustand';
import { immer } from 'zustand/middleware/immer';
type Store = {
type ProductsStore = {
products: productsSchema;
// Product-level actions
@@ -15,13 +15,13 @@ type Store = {
updateEvent: (productId: string, modelUuid: string, updates: Partial<EventsSchema>) => void;
// Point-level actions
addPoint: (productId: string, modelUuid: string, point: TransferPointSchema | VehiclePointSchema | RoboticArmPointSchema | MachinePointSchema | StoragePointSchema) => void;
addPoint: (productId: string, modelUuid: string, point: ConveyorPointSchema | VehiclePointSchema | RoboticArmPointSchema | MachinePointSchema | StoragePointSchema) => void;
removePoint: (productId: string, modelUuid: string, pointUuid: string) => void;
updatePoint: (
productId: string,
modelUuid: string,
pointUuid: string,
updates: Partial<TransferPointSchema | VehiclePointSchema | RoboticArmPointSchema | MachinePointSchema | StoragePointSchema>
updates: Partial<ConveyorPointSchema | VehiclePointSchema | RoboticArmPointSchema | MachinePointSchema | StoragePointSchema>
) => void;
// Action-level actions
@@ -29,12 +29,12 @@ type Store = {
productId: string,
modelUuid: string,
pointUuid: string,
action: TransferPointSchema['action'] | VehiclePointSchema['action'] | RoboticArmPointSchema['actions'][0] | MachinePointSchema['action'] | StoragePointSchema['action']
action: ConveyorPointSchema['action'] | VehiclePointSchema['action'] | RoboticArmPointSchema['actions'][0] | MachinePointSchema['action'] | StoragePointSchema['action']
) => void;
removeAction: (actionUuid: string) => void;
updateAction: (
actionUuid: string,
updates: Partial<TransferPointSchema['action'] | VehiclePointSchema['action'] | RoboticArmPointSchema['actions'][0] | MachinePointSchema['action'] | StoragePointSchema['action']>
updates: Partial<ConveyorPointSchema['action'] | VehiclePointSchema['action'] | RoboticArmPointSchema['actions'][0] | MachinePointSchema['action'] | StoragePointSchema['action']>
) => void;
// Trigger-level actions
@@ -52,7 +52,7 @@ type Store = {
getProductById: (productId: string) => { productName: string; productId: string; eventsData: EventsSchema[] } | undefined;
};
export const useProductStore = create<Store>()(
export const useProductStore = create<ProductsStore>()(
immer((set, get) => ({
products: [],
@@ -121,7 +121,7 @@ export const useProductStore = create<Store>()(
if (product) {
const event = product.eventsData.find(e => 'modelUuid' in e && e.modelUuid === modelUuid);
if (event && 'points' in event) {
(event as TransferEventSchema).points.push(point as TransferPointSchema);
(event as ConveyorEventSchema).points.push(point as ConveyorPointSchema);
} else if (event && 'point' in event) {
(event as VehicleSchemaEvent | RoboticArmSchemaEvent | MachineSchemaEvent | StorageSchemaEvent).point = point as any;
}
@@ -135,7 +135,7 @@ export const useProductStore = create<Store>()(
if (product) {
const event = product.eventsData.find(e => 'modelUuid' in e && e.modelUuid === modelUuid);
if (event && 'points' in event) {
(event as TransferEventSchema).points = (event as TransferEventSchema).points.filter(p => p.uuid !== pointUuid);
(event as ConveyorEventSchema).points = (event as ConveyorEventSchema).points.filter(p => p.uuid !== pointUuid);
} else if (event && 'point' in event && (event as any).point.uuid === pointUuid) {
// For events with single point, we can't remove it, only reset to empty
}
@@ -149,7 +149,7 @@ export const useProductStore = create<Store>()(
if (product) {
const event = product.eventsData.find(e => 'modelUuid' in e && e.modelUuid === modelUuid);
if (event && 'points' in event) {
const point = (event as TransferEventSchema).points.find(p => p.uuid === pointUuid);
const point = (event as ConveyorEventSchema).points.find(p => p.uuid === pointUuid);
if (point) {
Object.assign(point, updates);
}
@@ -167,7 +167,7 @@ export const useProductStore = create<Store>()(
if (product) {
const event = product.eventsData.find(e => 'modelUuid' in e && e.modelUuid === modelUuid);
if (event && 'points' in event) {
const point = (event as TransferEventSchema).points.find(p => p.uuid === pointUuid);
const point = (event as ConveyorEventSchema).points.find(p => p.uuid === pointUuid);
if (point) {
point.action = action as any;
}
@@ -187,8 +187,8 @@ export const useProductStore = create<Store>()(
for (const product of state.products) {
for (const event of product.eventsData) {
if ('points' in event) {
// Handle TransferEventSchema
for (const point of (event as TransferEventSchema).points) {
// Handle ConveyorEventSchema
for (const point of (event as ConveyorEventSchema).points) {
}
} else if ('point' in event) {
const point = (event as any).point;
@@ -211,7 +211,7 @@ export const useProductStore = create<Store>()(
for (const product of state.products) {
for (const event of product.eventsData) {
if ('points' in event) {
for (const point of (event as TransferEventSchema).points) {
for (const point of (event as ConveyorEventSchema).points) {
if (point.action && point.action.actionUuid === actionUuid) {
Object.assign(point.action, updates);
return;
@@ -241,7 +241,7 @@ export const useProductStore = create<Store>()(
for (const product of state.products) {
for (const event of product.eventsData) {
if ('points' in event) {
for (const point of (event as TransferEventSchema).points) {
for (const point of (event as ConveyorEventSchema).points) {
if (point.action && point.action.actionUuid === actionUuid) {
point.action.triggers.push(trigger);
return;
@@ -270,7 +270,7 @@ export const useProductStore = create<Store>()(
for (const product of state.products) {
for (const event of product.eventsData) {
if ('points' in event) {
for (const point of (event as TransferEventSchema).points) {
for (const point of (event as ConveyorEventSchema).points) {
if (point.action && 'triggers' in point.action) {
point.action.triggers = point.action.triggers.filter(t => t.triggerUuid !== triggerUuid);
}
@@ -297,7 +297,7 @@ export const useProductStore = create<Store>()(
for (const product of state.products) {
for (const event of product.eventsData) {
if ('points' in event) {
for (const point of (event as TransferEventSchema).points) {
for (const point of (event as ConveyorEventSchema).points) {
if (point.action && 'triggers' in point.action) {
const trigger = point.action.triggers.find(t => t.triggerUuid === triggerUuid);
if (trigger) {
@@ -336,4 +336,4 @@ export const useProductStore = create<Store>()(
return get().products.find(p => p.productId === productId);
}
}))
);
);

View File

@@ -0,0 +1,158 @@
import { create } from 'zustand';
import { immer } from 'zustand/middleware/immer';
interface StorageUnitStatus extends StorageSchemaEvent {
productId: string;
isActive: boolean;
idleTime: number;
activeTime: number;
currentLoad: number;
}
interface StorageUnitStore {
storageUnits: Record<string, StorageUnitStatus>;
// Actions
addStorageUnit: (productId: string, storageUnit: StorageSchemaEvent) => void;
removeStorageUnit: (modelUuid: string) => void;
updateStorageUnit: (
modelUuid: string,
updates: Partial<Omit<StorageUnitStatus, 'modelUuid' | 'productId'>>
) => void;
// Status updates
setStorageUnitActive: (modelUuid: string, isActive: boolean) => void;
setStorageUnitState: (modelUuid: string, newState: StorageUnitStatus['state']) => void;
// Load updates
updateStorageUnitLoad: (modelUuid: string, load: number) => void;
// Time tracking
incrementActiveTime: (modelUuid: string, incrementBy: number) => void;
incrementIdleTime: (modelUuid: string, incrementBy: number) => void;
// Helpers
getStorageUnitById: (modelUuid: string) => StorageUnitStatus | undefined;
getStorageUnitsByProduct: (productId: string) => StorageUnitStatus[];
getActiveStorageUnits: () => StorageUnitStatus[];
getIdleStorageUnits: () => StorageUnitStatus[];
getFullStorageUnits: () => StorageUnitStatus[];
getEmptyStorageUnits: () => StorageUnitStatus[];
}
export const useStorageUnitStore = create<StorageUnitStore>()(
immer((set, get) => ({
storageUnits: {},
// Actions
addStorageUnit: (productId, storageUnit) => {
set((state) => {
state.storageUnits[storageUnit.modelUuid] = {
...storageUnit,
productId,
isActive: false,
idleTime: 0,
activeTime: 0,
currentLoad: 0, // Initialize currentLoad to 0
state: 'idle',
};
});
},
removeStorageUnit: (modelUuid) => {
set((state) => {
delete state.storageUnits[modelUuid];
});
},
updateStorageUnit: (modelUuid, updates) => {
set((state) => {
const storageUnit = state.storageUnits[modelUuid];
if (storageUnit) {
Object.assign(storageUnit, updates);
}
});
},
// Status updates
setStorageUnitActive: (modelUuid, isActive) => {
set((state) => {
const storageUnit = state.storageUnits[modelUuid];
if (storageUnit) {
storageUnit.isActive = isActive;
}
});
},
setStorageUnitState: (modelUuid, newState) => {
set((state) => {
const storageUnit = state.storageUnits[modelUuid];
if (storageUnit) {
storageUnit.state = newState;
}
});
},
// Load updates
updateStorageUnitLoad: (modelUuid, load) => {
set((state) => {
const storageUnit = state.storageUnits[modelUuid];
if (storageUnit) {
storageUnit.currentLoad = load;
}
});
},
// Time tracking
incrementActiveTime: (modelUuid, incrementBy) => {
set((state) => {
const storageUnit = state.storageUnits[modelUuid];
if (storageUnit) {
storageUnit.activeTime += incrementBy;
}
});
},
incrementIdleTime: (modelUuid, incrementBy) => {
set((state) => {
const storageUnit = state.storageUnits[modelUuid];
if (storageUnit) {
storageUnit.idleTime += incrementBy;
}
});
},
// Helpers
getStorageUnitById: (modelUuid) => {
return get().storageUnits[modelUuid];
},
getStorageUnitsByProduct: (productId) => {
return Object.values(get().storageUnits).filter(
s => s.productId === productId
);
},
getActiveStorageUnits: () => {
return Object.values(get().storageUnits).filter(s => s.isActive);
},
getIdleStorageUnits: () => {
return Object.values(get().storageUnits).filter(
s => !s.isActive && s.state === 'idle'
);
},
getFullStorageUnits: () => {
return Object.values(get().storageUnits).filter(
s => s.currentLoad >= s.point.action.storageCapacity
);
},
getEmptyStorageUnits: () => {
return Object.values(get().storageUnits).filter(
s => s.currentLoad === 0
);
},
}))
);

View File

@@ -0,0 +1,149 @@
import { create } from 'zustand';
import { immer } from 'zustand/middleware/immer';
interface VehicleStatus extends VehicleSchemaEvent {
productId: string;
isActive: boolean;
idleTime: number;
activeTime: number;
currentLoad: number;
distanceTraveled: number;
}
interface VehiclesStore {
vehicles: Record<string, VehicleStatus>;
// Vehicle actions
addVehicle: (productId: string, event: VehicleSchemaEvent) => void;
removeVehicle: (modelUuid: string) => void;
updateVehicle: (
modelUuid: string,
updates: Partial<Omit<VehicleStatus, 'modelUuid' | 'productId'>>
) => void;
// Status updates
setVehicleActive: (modelUuid: string, isActive: boolean) => void;
updateVehicleLoad: (modelUuid: string, load: number) => void;
// State management
setVehicleState: (modelUuid: string, newState: VehicleStatus['state']) => void;
// Time tracking
incrementActiveTime: (modelUuid: string, incrementBy: number) => void;
incrementIdleTime: (modelUuid: string, incrementBy: number) => void;
// Helper functions
getVehicleById: (modelUuid: string) => VehicleStatus | undefined;
getVehiclesByProduct: (productId: string) => VehicleStatus[];
getActiveVehicles: () => VehicleStatus[];
getIdleVehicles: () => VehicleStatus[];
}
export const useVehicleStore = create<VehiclesStore>()(
immer((set, get) => ({
vehicles: {},
addVehicle: (productId, event) => {
set((state) => {
state.vehicles[event.modelUuid] = {
...event,
isActive: false,
productId,
idleTime: 0,
activeTime: 0,
currentLoad: 0,
distanceTraveled: 0,
};
});
},
removeVehicle: (modelUuid) => {
set((state) => {
delete state.vehicles[modelUuid];
});
},
updateVehicle: (modelUuid, updates) => {
set((state) => {
const vehicle = state.vehicles[modelUuid];
if (vehicle) {
Object.assign(vehicle, updates);
}
});
},
// Status updates
setVehicleActive: (modelUuid, isActive) => {
set((state) => {
const vehicle = state.vehicles[modelUuid];
if (vehicle) {
vehicle.isActive = isActive;
if (isActive) {
vehicle.state = 'running';
} else {
vehicle.state = vehicle.currentLoad > 0 ? 'idle' : 'stopped';
}
}
});
},
updateVehicleLoad: (modelUuid, load) => {
set((state) => {
const vehicle = state.vehicles[modelUuid];
if (vehicle) {
vehicle.currentLoad = load;
}
});
},
// State management
setVehicleState: (modelUuid, newState) => {
set((state) => {
const vehicle = state.vehicles[modelUuid];
if (vehicle) {
vehicle.state = newState;
}
});
},
// Time tracking
incrementActiveTime: (modelUuid, incrementBy) => {
set((state) => {
const vehicle = state.vehicles[modelUuid];
if (vehicle) {
vehicle.activeTime += incrementBy;
}
});
},
incrementIdleTime: (modelUuid, incrementBy) => {
set((state) => {
const vehicle = state.vehicles[modelUuid];
if (vehicle) {
vehicle.idleTime += incrementBy;
}
});
},
// Getters
getVehicleById: (modelUuid) => {
return get().vehicles[modelUuid];
},
getVehiclesByProduct: (productId) => {
return Object.values(get().vehicles).filter(
v => v.productId === productId
);
},
getActiveVehicles: () => {
return Object.values(get().vehicles).filter(v => v.isActive);
},
getIdleVehicles: () => {
return Object.values(get().vehicles).filter(
v => !v.isActive && v.currentLoad > 0
);
}
}))
);

View File

@@ -85,10 +85,15 @@ export const useZonePoints = create<ZonePointsState>((set) => ({
}));
export const useSelectedItem = create<any>((set: any) => ({
selectedItem: { name: "", id: "" },
selectedItem: { name: "", id: "", type: undefined },
setSelectedItem: (x: any) => set(() => ({ selectedItem: x })),
}));
export const useNavMesh = create<any>((set: any) => ({
navMesh: null,
setNavMesh: (x: any) => set({ navMesh: x }),
}));
export const useSelectedAssets = create<any>((set: any) => ({
selectedAssets: [],
setSelectedAssets: (x: any) => set(() => ({ selectedAssets: x })),

View File

@@ -1,6 +1,6 @@
import { create } from "zustand";
import { addingFloatingWidgets } from "../services/visulization/zone/addFloatingWidgets";
import { useSocketStore } from "./store";
import { addingFloatingWidgets } from "../../services/visulization/zone/addFloatingWidgets";
import { useSocketStore } from "../store";
import useChartStore from "./useChartStore";
type DroppedObject = {

View File

@@ -1,53 +1,53 @@
import { create } from "zustand";
type Side = "top" | "bottom" | "left" | "right";
interface Widget {
id: string;
type: string;
title: string;
panel: Side;
data: any;
}
interface SelectedZoneState {
zoneName: string;
activeSides: Side[];
panelOrder: Side[];
points: []
lockedPanels: Side[];
zoneId: string;
zoneViewPortTarget: number[];
zoneViewPortPosition: number[];
widgets: Widget[];
}
interface SelectedZoneStore {
selectedZone: SelectedZoneState;
setSelectedZone: (
zone:
| Partial<SelectedZoneState>
| ((prev: SelectedZoneState) => SelectedZoneState)
) => void;
}
export const useSelectedZoneStore = create<SelectedZoneStore>((set) => ({
selectedZone: {
zoneName: "", // Empty string initially
activeSides: [], // Empty array
panelOrder: [], // Empty array
lockedPanels: [], // Empty array
points: [],
zoneId: "",
zoneViewPortTarget: [],
zoneViewPortPosition: [],
widgets: [], // Empty array
},
setSelectedZone: (zone) =>
set((state) => ({
selectedZone:
typeof zone === "function"
? zone(state.selectedZone) // Handle functional updates
: { ...state.selectedZone, ...zone }, // Handle partial updates
})),
}));
import { create } from "zustand";
type Side = "top" | "bottom" | "left" | "right";
interface Widget {
id: string;
type: string;
title: string;
panel: Side;
data: any;
}
interface SelectedZoneState {
zoneName: string;
activeSides: Side[];
panelOrder: Side[];
points: []
lockedPanels: Side[];
zoneId: string;
zoneViewPortTarget: number[];
zoneViewPortPosition: number[];
widgets: Widget[];
}
interface SelectedZoneStore {
selectedZone: SelectedZoneState;
setSelectedZone: (
zone:
| Partial<SelectedZoneState>
| ((prev: SelectedZoneState) => SelectedZoneState)
) => void;
}
export const useSelectedZoneStore = create<SelectedZoneStore>((set) => ({
selectedZone: {
zoneName: "", // Empty string initially
activeSides: [], // Empty array
panelOrder: [], // Empty array
lockedPanels: [], // Empty array
points: [],
zoneId: "",
zoneViewPortTarget: [],
zoneViewPortPosition: [],
widgets: [], // Empty array
},
setSelectedZone: (zone) =>
set((state) => ({
selectedZone:
typeof zone === "function"
? zone(state.selectedZone) // Handle functional updates
: { ...state.selectedZone, ...zone }, // Handle partial updates
})),
}));