import { create } from "zustand"; import { immer } from "zustand/middleware/immer"; interface AisleStore { aisles: Aisles; setAisles: (aisles: Aisles) => Aisles; addAisle: (aisle: Aisle) => Aisle; updateAisle: (uuid: string, updated: Partial) => Aisle | undefined; removeAisle: (uuid: string) => Aisle | undefined; removePoint: (uuid: string) => Aisles; clearAisles: () => Aisles; setPosition: ( pointUuid: string, position: [number, number, number] ) => Aisle | undefined; setLayer: (pointUuid: string, layer: number) => Aisle | undefined; setColor: (aisleUuid: string, color: AisleColors) => Aisle | undefined; setSolidAisleWidth: (aisleUuid: string, width: number) => Aisle | undefined; setDashedAisleProperties: ( aisleUuid: string, props: { aisleWidth?: number; dashLength?: number; gapLength?: number } ) => Aisle | undefined; setDottedAisleProperties: ( aisleUuid: string, props: { dotRadius?: number; gapLength?: number } ) => Aisle | undefined; setArrowAisleWidth: (aisleUuid: string, width: number) => Aisle | undefined; setArrowsAisleProperties: ( aisleUuid: string, props: { aisleWidth?: number; aisleLength?: number; gapLength?: number } ) => Aisle | undefined; setArcAisleWidth: ( aisleUuid: string, props: { aisleWidth?: number; isFlipped: boolean } ) => Aisle | undefined; setCircleAisleWidth: (aisleUuid: string, width: number) => Aisle | undefined; setJunctionAisleProperties: ( aisleUuid: string, props: { aisleWidth?: number; isFlipped: boolean } ) => Aisle | undefined; getAisleById: (uuid: string) => Aisle | undefined; getAislesByPointId: (uuid: string) => Aisle[] | []; getAislePointById: (uuid: string) => Point | undefined; getConnectedPoints: (uuid: string) => Point[] | []; getAisleType: (uuid: string) => T | undefined; } export const createAisleStore = () => { return create()( immer((set, get) => ({ aisles: [], setAisles: (aisles) => { set((state) => { state.aisles = aisles; }); return aisles; }, addAisle: (aisle) => { set((state) => { state.aisles.push(aisle); }); return aisle; }, updateAisle: (uuid, updated) => { let updatedAisle: Aisle | undefined; set((state) => { const aisle = state.aisles.find((a) => a.aisleUuid === uuid); if (aisle) { Object.assign(aisle, updated); updatedAisle = JSON.parse(JSON.stringify(aisle)); } }); return updatedAisle; }, removeAisle: (uuid) => { let removedAisle: Aisle | undefined; set((state) => { const index = state.aisles.findIndex((a) => a.aisleUuid === uuid); if (index !== -1) { removedAisle = JSON.parse(JSON.stringify(state.aisles[index])); state.aisles.splice(index, 1); } }); return removedAisle; }, removePoint: (uuid) => { const removedAisles: Aisle[] = []; set((state) => { state.aisles = state.aisles.filter((aisle) => { const hasPoint = aisle.points.some( (point) => point.pointUuid === uuid ); if (hasPoint) { removedAisles.push(JSON.parse(JSON.stringify(aisle))); return false; } return true; }); }); return removedAisles; }, clearAisles: () => { const clearedAisles = get().aisles; set((state) => { state.aisles = []; }); return clearedAisles; }, setPosition: (pointUuid, position) => { let updatedAisle: Aisle | undefined; set((state) => { for (const aisle of state.aisles) { const point = aisle.points.find((p) => p.pointUuid === pointUuid); if (point) { point.position = position; updatedAisle = JSON.parse(JSON.stringify(aisle)); } } }); return updatedAisle; }, setLayer: (pointUuid, layer) => { let updatedAisle: Aisle | undefined; set((state) => { for (const aisle of state.aisles) { const point = aisle.points.find((p) => p.pointUuid === pointUuid); if (point) { point.layer = layer; updatedAisle = JSON.parse(JSON.stringify(aisle)); } } }); return updatedAisle; }, setColor: (aisleUuid, color) => { let updatedAisle: Aisle | undefined; set((state) => { const aisle = state.aisles.find((a) => a.aisleUuid === aisleUuid); if (aisle) { aisle.type.aisleColor = color; updatedAisle = JSON.parse(JSON.stringify(aisle)); } }); return updatedAisle; }, setSolidAisleWidth: (aisleUuid, width) => { let updatedAisle: Aisle | undefined; set((state) => { const aisle = state.aisles.find((a) => a.aisleUuid === aisleUuid); if (aisle && aisle.type.aisleType === "solid-aisle") { aisle.type.aisleWidth = width; updatedAisle = JSON.parse(JSON.stringify(aisle)); } }); return updatedAisle; }, setDashedAisleProperties: (aisleUuid, props) => { let updatedAisle: Aisle | undefined; set((state) => { const aisle = state.aisles.find((a) => a.aisleUuid === aisleUuid); if (aisle && aisle.type.aisleType === "dashed-aisle") { if (props.aisleWidth !== undefined) aisle.type.aisleWidth = props.aisleWidth; if (props.dashLength !== undefined) aisle.type.dashLength = props.dashLength; if (props.gapLength !== undefined) aisle.type.gapLength = props.gapLength; updatedAisle = JSON.parse(JSON.stringify(aisle)); } }); return updatedAisle; }, setDottedAisleProperties: (aisleUuid, props) => { let updatedAisle: Aisle | undefined; set((state) => { const aisle = state.aisles.find((a) => a.aisleUuid === aisleUuid); if (aisle && aisle.type.aisleType === "dotted-aisle") { if (props.dotRadius !== undefined) aisle.type.dotRadius = props.dotRadius; if (props.gapLength !== undefined) aisle.type.gapLength = props.gapLength; updatedAisle = JSON.parse(JSON.stringify(aisle)); } }); return updatedAisle; }, setArrowAisleWidth: (aisleUuid, width) => { let updatedAisle: Aisle | undefined; set((state) => { const aisle = state.aisles.find((a) => a.aisleUuid === aisleUuid); if (aisle && aisle.type.aisleType === "arrow-aisle") { aisle.type.aisleWidth = width; updatedAisle = JSON.parse(JSON.stringify(aisle)); } }); return updatedAisle; }, setArrowsAisleProperties: (aisleUuid, props) => { let updatedAisle: Aisle | undefined; set((state) => { const aisle = state.aisles.find((a) => a.aisleUuid === aisleUuid); if (aisle && aisle.type.aisleType === "arrows-aisle") { if (props.aisleWidth !== undefined) aisle.type.aisleWidth = props.aisleWidth; if (props.aisleLength !== undefined) aisle.type.aisleLength = props.aisleLength; if (props.gapLength !== undefined) aisle.type.gapLength = props.gapLength; updatedAisle = JSON.parse(JSON.stringify(aisle)); } }); return updatedAisle; }, setArcAisleWidth: (aisleUuid, props) => { let updatedAisle: Aisle | undefined; set((state) => { const aisle = state.aisles.find((a) => a.aisleUuid === aisleUuid); if (aisle && aisle.type.aisleType === "arc-aisle") { if (props.aisleWidth !== undefined) aisle.type.aisleWidth = props.aisleWidth; if (props.isFlipped !== undefined) aisle.type.isFlipped = props.isFlipped; updatedAisle = JSON.parse(JSON.stringify(aisle)); } }); return updatedAisle; }, setCircleAisleWidth: (aisleUuid, width) => { let updatedAisle: Aisle | undefined; set((state) => { const aisle = state.aisles.find((a) => a.aisleUuid === aisleUuid); if (aisle && aisle.type.aisleType === "circle-aisle") { aisle.type.aisleWidth = width; updatedAisle = JSON.parse(JSON.stringify(aisle)); } }); return updatedAisle; }, setJunctionAisleProperties: (aisleUuid, props) => { let updatedAisle: Aisle | undefined; set((state) => { const aisle = state.aisles.find((a) => a.aisleUuid === aisleUuid); if (aisle && aisle.type.aisleType === "junction-aisle") { if (props.aisleWidth !== undefined) aisle.type.aisleWidth = props.aisleWidth; if (props.isFlipped !== undefined) aisle.type.isFlipped = props.isFlipped; updatedAisle = JSON.parse(JSON.stringify(aisle)); } }); return updatedAisle; }, getAisleById: (uuid) => { return get().aisles.find((a) => a.aisleUuid === uuid); }, getAislesByPointId: (uuid) => { return get().aisles.filter((a) => { return a.points.some((p) => p.pointUuid === uuid); }) }, getAislePointById: (uuid) => { for (const aisle of get().aisles) { const point = aisle.points.find((p) => p.pointUuid === uuid); if (point) { return point; } } return undefined; }, getConnectedPoints: (uuid) => { const connected: Point[] = []; for (const aisle of get().aisles) { for (const point of aisle.points) { if (point.pointUuid === uuid) { connected.push(...aisle.points.filter((p) => p.pointUuid !== uuid)); } } } return connected; }, getAisleType: (uuid: string) => { const aisle = get().aisles.find((a) => a.aisleUuid === uuid); return aisle?.type as T | undefined; }, })) ) } export type AisleStoreType = ReturnType;