first commit

This commit is contained in:
2025-06-10 15:28:23 +05:30
commit e22a2dc275
699 changed files with 100382 additions and 0 deletions

View File

@@ -0,0 +1,710 @@
import * as THREE from "three";
import { create } from "zustand";
import { io } from "socket.io-client";
import * as CONSTANTS from "../../types/world/worldConstants";
export const useSocketStore = create<any>((set: any, get: any) => ({
socket: null,
initializeSocket: (email?: string, organization?: string, token?: string) => {
const existingSocket = get().socket;
if (existingSocket) {
return;
}
const socket = io(
`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/Builder_v1`,
{
reconnection: true,
auth: { token },
}
);
const visualizationSocket = io(
`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/Visualization_v1`,
{
reconnection: true,
auth: { token },
}
);
const dashBoardSocket = io(
`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/dashboard`,
{
reconnection: true,
auth: { token },
}
);
const projectSocket = io(
`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/project`,
{
reconnection: true,
auth: { token },
}
);
set({ socket, visualizationSocket, dashBoardSocket, projectSocket });
},
disconnectSocket: () => {
set((state: any) => {
state.socket?.disconnect();
state.visualizationSocket?.disconnect();
state.dashBoardSocket?.disconnect();
state.projectSocket?.disconnect();
return { socket: null };
});
},
}));
// export const useSocketStore = create<any>((set: any, get: any) => ({
// socket: null,
// initializeSocket: (
// email: string,
// organization: string,
// userId?: string,
// token?: string
// ) => {
// const existingSocket = get().socket;
// if (existingSocket) {
// return;
// }
// const socket = io(
// `http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/Builder`,
// {
// reconnection: true,
// auth: { email, organization },
// }
// );
// const visualizationSocket = io(
// `http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/Visualization`,
// {
// reconnection: true,
// auth: { email, organization },
// }
// );
// const dashBoardSocket = io(
// `http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/dashboard`,
// {
// reconnection: true,
// auth: { token },
// }
// );
// // const dashBoardSocket = io(
// // `http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/project`,
// // {
// // reconnection: true,
// // auth: { token },
// // }
// // );
// set({ socket, visualizationSocket, dashBoardSocket });
// },
// disconnectSocket: () => {
// set((state: any) => {
// state.socket?.disconnect();
// state.visualizationSocket?.disconnect();
// state.dashBoardSocket?.disconnect();
// return { socket: null };
// });
// },
// }));
export const useLoadingProgress = create<{
loadingProgress: number;
setLoadingProgress: (x: number) => void;
}>((set) => ({
loadingProgress: 1,
setLoadingProgress: (x: number) => set({ loadingProgress: x }),
}));
export const useOrganization = create<any>((set: any) => ({
organization: "",
setOrganization: (x: any) => set(() => ({ organization: x })),
}));
export const useToggleView = create<any>((set: any) => ({
toggleView: false,
setToggleView: (x: any) => set(() => ({ toggleView: x })),
}));
export const useUpdateScene = create<any>((set: any) => ({
updateScene: false,
setUpdateScene: (x: any) => set(() => ({ updateScene: x })),
}));
export const useWalls = create<any>((set: any) => ({
walls: [],
setWalls: (x: any) => set(() => ({ walls: x })),
}));
export const useRoomsState = create<any>((set: any) => ({
roomsState: [],
setRoomsState: (x: any) => set(() => ({ roomsState: x })),
}));
export const useZones = create<any>((set: any) => ({
zones: [],
setZones: (callback: any) =>
set((state: any) => ({
zones: typeof callback === "function" ? callback(state.zones) : callback,
})),
}));
interface ZonePointsState {
zonePoints: THREE.Vector3[];
setZonePoints: (points: THREE.Vector3[]) => void;
}
export const useZonePoints = create<ZonePointsState>((set) => ({
zonePoints: [],
setZonePoints: (points) => set({ zonePoints: points }),
}));
export const useSelectedItem = create<any>((set: any) => ({
selectedItem: {
name: "",
id: "",
type: undefined,
category: "",
subCatergory: "",
},
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 })),
}));
export const useLayers = create<any>((set: any) => ({
Layers: 1,
setLayers: (x: any) => set(() => ({ Layers: x })),
}));
export const useCamPosition = create<any>((set: any) => ({
camPosition: { x: undefined, y: undefined, z: undefined },
setCamPosition: (newCamPosition: any) => set({ camPosition: newCamPosition }),
}));
export const useMenuVisible = create<any>((set: any) => ({
menuVisible: false,
setMenuVisible: (x: any) => set(() => ({ menuVisible: x })),
}));
export const useDeleteTool = create<any>((set: any) => ({
deleteTool: false,
setDeleteTool: (x: any) => set(() => ({ deleteTool: x })),
}));
export const useToolMode = create<any>((set: any) => ({
toolMode: null,
setToolMode: (x: any) => set(() => ({ toolMode: x })),
}));
export const useNewLines = create<any>((set: any) => ({
newLines: [],
setNewLines: (x: any) => set(() => ({ newLines: x })),
}));
export const useDeletedLines = create<any>((set: any) => ({
deletedLines: [],
setDeletedLines: (x: any) => set(() => ({ deletedLines: x })),
}));
export const useMovePoint = create<any>((set: any) => ({
movePoint: false,
setMovePoint: (x: any) => set(() => ({ movePoint: x })),
}));
export const useDeletePointOrLine = create<any>((set: any) => ({
deletePointOrLine: false,
setDeletePointOrLine: (x: any) => set(() => ({ deletePointOrLine: x })),
}));
export const useWallItems = create<any>((set: any) => ({
wallItems: [],
setWallItems: (callback: any) =>
set((state: any) => ({
wallItems:
typeof callback === "function" ? callback(state.wallItems) : callback,
})),
}));
export const useSelectedWallItem = create<any>((set: any) => ({
selectedWallItem: null,
setSelectedWallItem: (x: any) => set(() => ({ selectedWallItem: x })),
}));
export const useSelectedFloorItem = create<any>((set: any) => ({
selectedFloorItem: null,
setSelectedFloorItem: (x: any) => set(() => ({ selectedFloorItem: x })),
}));
export const useDeletableFloorItem = create<any>((set: any) => ({
deletableFloorItem: null,
setDeletableFloorItem: (x: any) => set(() => ({ deletableFloorItem: x })),
}));
export const useSetScale = create<any>((set: any) => ({
scale: null,
setScale: (x: any) => set(() => ({ scale: x })),
}));
export const useRoofVisibility = create<any>((set: any) => ({
roofVisibility: false,
setRoofVisibility: (x: any) => set(() => ({ roofVisibility: x })),
}));
export const useWallVisibility = create<any>((set: any) => ({
wallVisibility: false,
setWallVisibility: (x: any) => set(() => ({ wallVisibility: x })),
}));
export const useShadows = create<any>((set: any) => ({
shadows: false,
setShadows: (x: any) => set(() => ({ shadows: x })),
}));
export const useSunPosition = create<any>((set: any) => ({
sunPosition: { x: undefined, y: undefined, z: undefined },
setSunPosition: (newSuntPosition: any) =>
set({ sunPosition: newSuntPosition }),
}));
export const useRemoveLayer = create<any>((set: any) => ({
removeLayer: false,
setRemoveLayer: (x: any) => set(() => ({ removeLayer: x })),
}));
export const useRemovedLayer = create<any>((set: any) => ({
removedLayer: null,
setRemovedLayer: (x: any) => set(() => ({ removedLayer: x })),
}));
export const useProjectName = create<any>((set: any) => ({
projectName: "Creating Your Project",
setProjectName: (x: any) => set({ projectName: x }),
}));
export const useActiveLayer = create<any>((set: any) => ({
activeLayer: 1,
setActiveLayer: (x: any) => set({ activeLayer: x }),
}));
interface RefTextUpdateState {
refTextupdate: number;
setRefTextUpdate: (
callback: (currentValue: number) => number | number
) => void;
}
export const useRefTextUpdate = create<RefTextUpdateState>((set) => ({
refTextupdate: -1000,
setRefTextUpdate: (callback) =>
set((state) => ({
refTextupdate:
typeof callback === "function"
? callback(state.refTextupdate)
: callback,
})),
}));
export const useResetCamera = create<any>((set: any) => ({
resetCamera: false,
setResetCamera: (x: any) => set({ resetCamera: x }),
}));
export const useAddAction = create<any>((set: any) => ({
addAction: null,
setAddAction: (x: any) => set({ addAction: x }),
}));
export const useActiveTool = create<any>((set: any) => ({
activeTool: "cursor",
setActiveTool: (x: any) => set({ activeTool: x }),
}));
export const useActiveSubTool = create<any>((set: any) => ({
activeSubTool: "cursor",
setActiveSubTool: (x: any) => set({ activeSubTool: x }),
}));
export const use2DUndoRedo = create<any>((set: any) => ({
is2DUndoRedo: null,
set2DUndoRedo: (x: any) => set({ is2DUndoRedo: x }),
}));
export const useElevation = create<any>((set: any) => ({
elevation: 45,
setElevation: (x: any) => set({ elevation: x }),
}));
export const useAzimuth = create<any>((set: any) => ({
azimuth: -160,
setAzimuth: (x: any) => set({ azimuth: x }),
}));
export const useRenderDistance = create<any>((set: any) => ({
renderDistance: 40,
setRenderDistance: (x: any) => set({ renderDistance: x }),
}));
export const useCamMode = create<any>((set: any) => ({
camMode: "ThirdPerson",
setCamMode: (x: any) => set({ camMode: x }),
}));
export const useUserName = create<any>((set: any) => ({
userName: "",
setUserName: (x: any) => set({ userName: x }),
}));
export const useRenameModeStore = create<any>((set: any) => ({
isRenameMode: false,
setIsRenameMode: (state: boolean) => set({ isRenameMode: state }),
}));
export const useObjectPosition = create<any>((set: any) => ({
objectPosition: { x: undefined, y: undefined, z: undefined },
setObjectPosition: (newObjectPosition: any) =>
set({ objectPosition: newObjectPosition }),
}));
export const useObjectRotation = create<any>((set: any) => ({
objectRotation: { x: undefined, y: undefined, z: undefined },
setObjectRotation: (newObjectRotation: any) =>
set({ objectRotation: newObjectRotation }),
}));
export const useDrieTemp = create<any>((set: any) => ({
drieTemp: undefined,
setDrieTemp: (x: any) => set({ drieTemp: x }),
}));
export const useActiveUsers = create<any>((set: any) => ({
activeUsers: [],
setActiveUsers: (callback: (prev: any[]) => any[] | any[]) =>
set((state: { activeUsers: any[] }) => ({
activeUsers:
typeof callback === "function" ? callback(state.activeUsers) : callback,
})),
}));
export const useDrieUIValue = create<any>((set: any) => ({
drieUIValue: { touch: null, temperature: null, humidity: null },
setDrieUIValue: (x: any) =>
set((state: any) => ({ drieUIValue: { ...state.drieUIValue, ...x } })),
setTouch: (value: any) =>
set((state: any) => ({
drieUIValue: { ...state.drieUIValue, touch: value },
})),
setTemperature: (value: any) =>
set((state: any) => ({
drieUIValue: { ...state.drieUIValue, temperature: value },
})),
setHumidity: (value: any) =>
set((state: any) => ({
drieUIValue: { ...state.drieUIValue, humidity: value },
})),
}));
export const useStartSimulation = create<any>((set: any) => ({
startSimulation: false,
setStartSimulation: (x: any) => set({ startSimulation: x }),
}));
export const useEyeDropMode = create<any>((set: any) => ({
eyeDropMode: false,
setEyeDropMode: (x: any) => set({ eyeDropMode: x }),
}));
export const useEditingPoint = create<any>((set: any) => ({
editingPoint: false,
setEditingPoint: (x: any) => set({ editingPoint: x }),
}));
export const usezoneTarget = create<any>((set: any) => ({
zoneTarget: [],
setZoneTarget: (x: any) => set({ zoneTarget: x }),
}));
export const usezonePosition = create<any>((set: any) => ({
zonePosition: [],
setZonePosition: (x: any) => set({ zonePosition: x }),
}));
interface EditPositionState {
Edit: boolean;
setEdit: (value: boolean) => void;
}
export const useEditPosition = create<EditPositionState>((set) => ({
Edit: false,
setEdit: (value) => set({ Edit: value }),
}));
export const useAsset3dWidget = create<any>((set: any) => ({
widgetSelect: "",
setWidgetSelect: (x: any) => set({ widgetSelect: x }),
}));
export const useWidgetSubOption = create<any>((set: any) => ({
widgetSubOption: "2D",
setWidgetSubOption: (x: any) => set({ widgetSubOption: x }),
}));
export const useLimitDistance = create<any>((set: any) => ({
limitDistance: true,
setLimitDistance: (x: any) => set({ limitDistance: x }),
}));
export const useTileDistance = create<any>((set: any) => ({
gridValue: {
size: CONSTANTS.gridConfig.size,
divisions: CONSTANTS.gridConfig.divisions,
},
planeValue: {
height: CONSTANTS.planeConfig.height,
width: CONSTANTS.planeConfig.width,
},
setGridValue: (value: any) =>
set((state: any) => ({
gridValue: { ...state.gridValue, ...value },
})),
setPlaneValue: (value: any) =>
set((state: any) => ({
planeValue: { ...state.planeValue, ...value },
})),
}));
export const usePlayAgv = create<any>((set, get) => ({
PlayAgv: [],
setPlayAgv: (updateFn: (prev: any[]) => any[]) =>
set({ PlayAgv: updateFn(get().PlayAgv) }),
}));
// Define the Asset type
type Asset = {
id: string;
name: string;
position?: [number, number, number]; // Optional: 3D position
rotation?: { x: number; y: number; z: number }; // Optional: Euler rotation
};
// Zustand store type
type ZoneAssetState = {
zoneAssetId: Asset | null;
setZoneAssetId: (asset: Asset | null) => void;
};
// Zustand store
export const useZoneAssetId = create<ZoneAssetState>((set) => ({
zoneAssetId: null,
setZoneAssetId: (asset) => set({ zoneAssetId: asset }),
}));
// version visible hidden
interface VersionHistoryState {
viewVersionHistory: boolean;
setVersionHistory: (value: boolean) => void;
}
const useVersionHistoryStore = create<VersionHistoryState>((set) => ({
viewVersionHistory: false,
setVersionHistory: (value) => set({ viewVersionHistory: value }),
}));
export default useVersionHistoryStore;
interface ShortcutStore {
showShortcuts: boolean;
setShowShortcuts: (value: boolean) => void;
toggleShortcuts: () => void;
}
export const useShortcutStore = create<ShortcutStore>((set) => ({
showShortcuts: false,
setShowShortcuts: (value) => set({ showShortcuts: value }),
toggleShortcuts: () =>
set((state) => ({ showShortcuts: !state.showShortcuts })),
}));
export const useMachineCount = create<any>((set: any) => ({
machineCount: 0,
setMachineCount: (x: any) => set({ machineCount: x }),
}));
export const useMachineUptime = create<any>((set: any) => ({
machineActiveTime: 0,
setMachineActiveTime: (x: any) => set({ machineActiveTime: x }),
}));
export const useMaterialCycle = create<any>((set: any) => ({
materialCycleTime: 0,
setMaterialCycleTime: (x: any) => set({ materialCycleTime: x }),
}));
export const useThroughPutData = create<any>((set: any) => ({
throughputData: 0,
setThroughputData: (x: any) => set({ throughputData: x }),
}));
export const useProductionCapacityData = create<any>((set: any) => ({
productionCapacityData: 0,
setProductionCapacityData: (x: any) => set({ productionCapacityData: x }),
}));
export const useProcessBar = create<any>((set: any) => ({
processBar: [],
setProcessBar: (x: any) => set({ processBar: x }),
}));
export const useDfxUpload = create<any>((set: any) => ({
dfxuploaded: [],
dfxWallGenerate: [],
objValue: { x: 0, y: 0, z: 0 },
setDfxUploaded: (x: any) => set({ dfxuploaded: x }),
setDfxGenerate: (x: any) => set({ dfxWallGenerate: x }),
setObjValue: (x: any) => set({ objValue: x }),
}));
type InputValuesStore = {
inputValues: Record<string, string>;
setInputValues: (values: Record<string, string>) => void;
updateInputValue: (label: string, value: string) => void; // <- New
};
export const useInputValues = create<InputValuesStore>((set) => ({
inputValues: {},
setInputValues: (values) => set({ inputValues: values }),
updateInputValue: (label, value) =>
set((state) => ({
inputValues: {
...state.inputValues,
[label]: value,
},
})),
}));
export interface ROISummaryData {
productName: string;
roiPercentage: number;
paybackPeriod: number;
totalCost: number;
revenueGenerated: number;
netProfit: number;
netLoss: number;
}
interface ROISummaryStore {
roiSummary: ROISummaryData;
setRoiSummaryData: (values: ROISummaryData) => void;
}
export const useROISummaryData = create<ROISummaryStore>((set) => ({
roiSummary: {
productName: "",
roiPercentage: 0,
paybackPeriod: 0,
totalCost: 0,
revenueGenerated: 0,
netProfit: 0,
netLoss: 0,
},
setRoiSummaryData: (values) => set({ roiSummary: values }),
}));
interface CompareStore {
comparePopUp: boolean;
setComparePopUp: (value: boolean) => void;
toggleComparePopUp: () => void;
}
export const useCompareStore = create<CompareStore>((set) => ({
comparePopUp: true,
setComparePopUp: (value) => set({ comparePopUp: value }),
toggleComparePopUp: () =>
set((state) => ({ comparePopUp: !state.comparePopUp })),
}));
// Save state store
interface SaveVersionStore {
isVersionSaved: boolean;
setIsVersionSaved: (value: boolean) => void;
}
export const useSaveVersion = create<SaveVersionStore>((set) => ({
isVersionSaved: false,
setIsVersionSaved: (value: boolean) => set({ isVersionSaved: value }),
}));
// Version object type
export interface Version {
id: string;
versionLabel: string;
versionName?: string;
timestamp: string;
savedBy: string;
description?: string;
}
// Version list store
interface VersionListStore {
versions: Version[];
addVersion: (version: Version) => void;
clearVersions: () => void;
setVersions: (newVersions: Version[]) => void;
updateVersion: (id: string, data: Partial<Version>) => void; // ✅ Added
}
export const useVersionStore = create<VersionListStore>((set) => ({
versions: [],
addVersion: (newVersion) =>
set((state) => ({
versions: [newVersion, ...state.versions],
})),
clearVersions: () => set({ versions: [] }),
setVersions: (newVersions) => set({ versions: newVersions }),
updateVersion: (id, data) =>
set((state) => ({
versions: state.versions.map((version) =>
version.id === id ? { ...version, ...data } : version
),
})),
}));
interface ViewSceneState {
viewSceneLabels: boolean;
setViewSceneLabels: (value: boolean | ((prev: boolean) => boolean)) => void;
}
export const useViewSceneStore = create<ViewSceneState>((set) => ({
viewSceneLabels: getInitialViewSceneLabels(),
setViewSceneLabels: (value) => {
set((state) => {
const newValue =
typeof value === 'function' ? value(state.viewSceneLabels) : value;
// Store in localStorage manually
localStorage.setItem('viewSceneLabels', JSON.stringify(newValue));
return { viewSceneLabels: newValue };
});
},
}));
function getInitialViewSceneLabels(): boolean {
if (typeof window === 'undefined') return false; // SSR safety
const saved = localStorage.getItem('viewSceneLabels');
return saved ? JSON.parse(saved) : false;
}

View File

@@ -0,0 +1,247 @@
import { create } from "zustand";
import { immer } from "zustand/middleware/immer";
interface AisleStore {
aisles: Aisles;
setAisles: (aisles: Aisles) => void;
addAisle: (aisle: Aisle) => void;
updateAisle: (uuid: string, updated: Partial<Aisle>) => void;
removeAisle: (uuid: string) => void;
removePoint: (uuid: string) => Aisles;
setPosition: (
pointUuid: string,
position: [number, number, number]
) => Aisle | undefined;
setLayer: (pointUuid: string, layer: number) => void;
setColor: (aisleUuid: string, color: AisleColors) => void;
// Type-specific setters
setSolidAisleWidth: (aisleUuid: string, width: number) => void;
setDashedAisleProperties: (
aisleUuid: string,
props: { aisleWidth?: number; dashLength?: number; gapLength?: number }
) => void;
setDottedAisleProperties: (
aisleUuid: string,
props: { dotRadius?: number; gapLength?: number }
) => void;
setArrowAisleWidth: (aisleUuid: string, width: number) => void;
setArrowsAisleProperties: (
aisleUuid: string,
props: { aisleWidth?: number; aisleLength?: number; gapLength?: number }
) => void;
setArcAisleWidth: (
aisleUuid: string,
props: { aisleWidth?: number; isFlipped: boolean }
) => void;
setCircleAisleWidth: (aisleUuid: string, width: number) => void;
setJunctionAisleProperties: (
aisleUuid: string,
props: { aisleWidth?: number; isFlipped: boolean }
) => void;
getAisleById: (uuid: string) => Aisle | undefined;
getAislesByPointId: (uuid: string) => Aisle[] | [];
getAislePointById: (uuid: string) => Point | undefined;
getConnectedPoints: (uuid: string) => Point[] | [];
getAisleType: <T extends AisleType>(uuid: string) => T | undefined;
}
export const useAisleStore = create<AisleStore>()(
immer((set, get) => ({
aisles: [],
setAisles: (aisles) =>
set((state) => {
state.aisles = aisles;
}),
addAisle: (aisle) =>
set((state) => {
state.aisles.push(aisle);
}),
updateAisle: (uuid, updated) =>
set((state) => {
const aisle = state.aisles.find((a) => a.aisleUuid === uuid);
if (aisle) {
Object.assign(aisle, updated);
}
}),
removeAisle: (uuid) =>
set((state) => {
state.aisles = state.aisles.filter((a) => a.aisleUuid !== uuid);
}),
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;
},
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) =>
set((state) => {
for (const aisle of state.aisles) {
const point = aisle.points.find((p) => p.pointUuid === pointUuid);
if (point) {
point.layer = layer;
}
}
}),
setColor: (aisleUuid, color) =>
set((state) => {
const aisle = state.aisles.find((a) => a.aisleUuid === aisleUuid);
if (aisle) {
aisle.type.aisleColor = color;
}
}),
// Type-specific property setters
setSolidAisleWidth: (aisleUuid, width) =>
set((state) => {
const aisle = state.aisles.find((a) => a.aisleUuid === aisleUuid);
if (aisle && aisle.type.aisleType === "solid-aisle") {
aisle.type.aisleWidth = width;
}
}),
setDashedAisleProperties: (aisleUuid, props) =>
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;
}
}),
setDottedAisleProperties: (aisleUuid, props) =>
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;
}
}),
setArrowAisleWidth: (aisleUuid, width) =>
set((state) => {
const aisle = state.aisles.find((a) => a.aisleUuid === aisleUuid);
if (aisle && aisle.type.aisleType === "arrow-aisle") {
aisle.type.aisleWidth = width;
}
}),
setArrowsAisleProperties: (aisleUuid, props) =>
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;
}
}),
setArcAisleWidth: (aisleUuid, props) =>
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;
}
}),
setCircleAisleWidth: (aisleUuid, width) =>
set((state) => {
const aisle = state.aisles.find((a) => a.aisleUuid === aisleUuid);
if (aisle && aisle.type.aisleType === "circle-aisle") {
aisle.type.aisleWidth = width;
}
}),
setJunctionAisleProperties: (aisleUuid, props) =>
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;
}
}),
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: <T extends AisleType>(uuid: string) => {
const aisle = get().aisles.find((a) => a.aisleUuid === uuid);
return aisle?.type as T | undefined;
},
}))
);

View File

@@ -0,0 +1,231 @@
import { create } from 'zustand';
import { immer } from 'zustand/middleware/immer';
interface AssetsStore {
assets: Assets;
// Asset CRUD operations
addAsset: (asset: Asset) => void;
removeAsset: (modelUuid: string) => void;
updateAsset: (modelUuid: string, updates: Partial<Asset>) => void;
setAssets: (assets: Assets) => void;
// Asset properties
setName: (modelUuid: string, newName: string) => void;
setPosition: (modelUuid: string, position: [number, number, number]) => void;
setRotation: (modelUuid: string, rotation: [number, number, number]) => void;
setLock: (modelUuid: string, isLocked: boolean) => void;
setCollision: (modelUuid: string, isCollidable: boolean) => void;
setVisibility: (modelUuid: string, isVisible: boolean) => void;
setOpacity: (modelUuid: string, opacity: number) => void;
// Animation controls
setAnimation: (modelUuid: string, animation: string) => void;
setCurrentAnimation: (modelUuid: string, current: string, isPlaying: boolean) => void;
addAnimation: (modelUuid: string, animation: string) => void;
removeAnimation: (modelUuid: string, animation: string) => void;
// Event data operations
addEventData: (modelUuid: string, eventData: Asset['eventData']) => void;
updateEventData: (modelUuid: string, updates: Partial<Asset['eventData']>) => void;
removeEventData: (modelUuid: string) => void;
// Helper functions
getAssetById: (modelUuid: string) => Asset | undefined;
getAssetByPointUuid: (pointUuid: string) => Asset | undefined;
hasAsset: (modelUuid: string) => boolean;
}
export const useAssetsStore = create<AssetsStore>()(
immer((set, get) => ({
assets: [],
// Asset CRUD operations
addAsset: (asset) => {
set((state) => {
if (!state.assets.some(a => a.modelUuid === asset.modelUuid)) {
state.assets.push(asset);
}
});
},
removeAsset: (modelUuid) => {
set((state) => {
state.assets = state.assets.filter(a => a.modelUuid !== modelUuid);
});
},
updateAsset: (modelUuid, updates) => {
set((state) => {
const asset = state.assets.find(a => a.modelUuid === modelUuid);
if (asset) {
Object.assign(asset, updates);
}
});
},
setAssets: (assets) => {
set((state) => {
state.assets = assets;
});
},
// Asset properties
setName: (modelUuid, newName) => {
set((state) => {
const asset = state.assets.find(a => a.modelUuid === modelUuid);
if (asset) {
asset.modelName = newName;
}
});
},
setPosition: (modelUuid, position) => {
set((state) => {
const asset = state.assets.find(a => a.modelUuid === modelUuid);
if (asset) {
asset.position = position;
}
});
},
setRotation: (modelUuid, rotation) => {
set((state) => {
const asset = state.assets.find(a => a.modelUuid === modelUuid);
if (asset) {
asset.rotation = rotation;
}
});
},
setLock: (modelUuid, isLocked) => {
set((state) => {
const asset = state.assets.find(a => a.modelUuid === modelUuid);
if (asset) {
asset.isLocked = isLocked;
}
});
},
setCollision: (modelUuid, isCollidable) => {
set((state) => {
const asset = state.assets.find(a => a.modelUuid === modelUuid);
if (asset) {
asset.isCollidable = isCollidable;
}
});
},
setVisibility: (modelUuid, isVisible) => {
set((state) => {
const asset = state.assets.find(a => a.modelUuid === modelUuid);
if (asset) {
asset.isVisible = isVisible;
}
});
},
setOpacity: (modelUuid, opacity) => {
set((state) => {
const asset = state.assets.find(a => a.modelUuid === modelUuid);
if (asset) {
asset.opacity = opacity;
}
});
},
// Animation controls
setAnimation: (modelUuid, animation) => {
set((state) => {
const asset = state.assets.find(a => a.modelUuid === modelUuid);
if (asset) {
if (!asset.animationState) {
asset.animationState = { current: animation, playing: false };
} else {
asset.animationState.current = animation;
}
}
});
},
setCurrentAnimation: (modelUuid, current, isPlaying) => {
set((state) => {
const asset = state.assets.find(a => a.modelUuid === modelUuid);
if (asset?.animationState) {
asset.animationState.current = current;
asset.animationState.playing = isPlaying;
}
});
},
addAnimation: (modelUuid, animation) => {
set((state) => {
const asset = state.assets.find(a => a.modelUuid === modelUuid);
if (asset) {
if (!asset.animations) {
asset.animations = [animation];
} else if (!asset.animations.includes(animation)) {
asset.animations.push(animation);
}
}
});
},
removeAnimation: (modelUuid, animation) => {
set((state) => {
const asset = state.assets.find(a => a.modelUuid === modelUuid);
if (asset?.animations) {
asset.animations = asset.animations.filter(a => a !== animation);
if (asset.animationState?.current === animation) {
asset.animationState.playing = false;
asset.animationState.current = '';
}
}
});
},
// Event data operations
addEventData: (modelUuid, eventData) => {
set((state) => {
const asset = state.assets.find(a => a.modelUuid === modelUuid);
if (asset) {
asset.eventData = eventData;
}
});
},
updateEventData: (modelUuid, updates) => {
set((state) => {
const asset = state.assets.find(a => a.modelUuid === modelUuid);
if (asset?.eventData) {
asset.eventData = { ...asset.eventData, ...updates };
}
});
},
removeEventData: (modelUuid) => {
set((state) => {
const asset = state.assets.find(a => a.modelUuid === modelUuid);
if (asset) {
delete asset.eventData;
}
});
},
// Helper functions
getAssetById: (modelUuid) => {
return get().assets.find(a => a.modelUuid === modelUuid);
},
getAssetByPointUuid: (pointUuid) => {
return get().assets.find(asset =>
asset.eventData?.point?.uuid === pointUuid ||
asset.eventData?.points?.some(p => p.uuid === pointUuid)
);
},
hasAsset: (modelUuid) => {
return get().assets.some(a => a.modelUuid === modelUuid);
}
}))
);

View File

@@ -0,0 +1,211 @@
import { Object3D } from 'three';
import { create } from 'zustand';
import { immer } from 'zustand/middleware/immer';
interface BuilderState {
// Common properties
hoveredPoint: Point | null;
snappedPoint: Point | null;
snappedPosition: [number, number, number] | null;
// Wall
wallThickness: number;
wallHeight: number;
setWallThickness: (thickness: number) => void;
setWallHeight: (height: number) => void;
// Aisle
selectedAisle: Object3D | null;
aisleType: AisleTypes;
aisleWidth: number;
aisleColor: AisleColors;
// Dashed aisle properties
dashLength: number;
gapLength: number;
// Dotted aisle properties
dotRadius: number;
// Arrows aisle properties
aisleLength: number;
// Junction aisle properties
isFlipped: boolean;
// Setters for common properties
setHoveredPoint: (point: Point | null) => void;
setSnappedPoint: (point: Point | null) => void;
setSnappedPosition: (position: [number, number, number] | null) => void;
setSelectedAisle: (aisle: Object3D | null) => void;
setAisleType: (type: AisleTypes) => void;
setAisleWidth: (width: number) => void;
setAisleColor: (color: AisleColors) => void;
// Setters for dashed aisle
setDashLength: (length: number) => void;
setGapLength: (length: number) => void;
// Setters for dotted aisle
setDotRadius: (radius: number) => void;
// Setters for arrows aisle
setAisleLength: (length: number) => void;
// Setters for junction aisle
setIsFlipped: (isFlipped: boolean) => void;
// Batch setters
setDashedAisleProperties: (width: number, dashLength: number, gapLength: number) => void;
setDottedAisleProperties: (width: number, dotRadius: number, gapLength: number) => void;
setArrowsAisleProperties: (width: number, aisleLength: number, gapLength: number) => void;
setAisleProperties: (type: AisleTypes, width: number, color: AisleColors) => void;
}
export const useBuilderStore = create<BuilderState>()(
immer((set) => ({
// Default values
hoveredPoint: null,
snappedPoint: null,
snappedPosition: null,
// Wall
wallThickness: 0.1,
wallHeight: 7,
setWallThickness: (thickness: number) => {
set((state) => {
state.wallThickness = thickness;
})
},
setWallHeight: (height: number) => {
set((state) => {
state.wallHeight = height;
})
},
// Aisle
selectedAisle: null,
aisleType: 'solid-aisle',
aisleWidth: 0.1,
aisleColor: 'yellow',
dashLength: 0.5,
gapLength: 0.3,
dotRadius: 0.1,
aisleLength: 0.6,
isFlipped: false,
// Individual setters
setHoveredPoint: (point: Point | null) => {
set((state) => {
state.hoveredPoint = point;
});
},
setSnappedPoint: (point: Point | null) => {
set((state) => {
state.snappedPoint = point;
});
},
setSnappedPosition: (position: [number, number, number] | null) => {
set((state) => {
state.snappedPosition = position;
});
},
setSelectedAisle: (aisle: Object3D | null) => {
set((state) => {
state.selectedAisle = aisle;
});
},
setAisleType: (type) => {
set((state) => {
state.aisleType = type;
});
},
setAisleWidth: (width) => {
set((state) => {
state.aisleWidth = width;
});
},
setAisleColor: (color) => {
set((state) => {
state.aisleColor = color;
});
},
setDashLength: (length) => {
set((state) => {
state.dashLength = length;
});
},
setGapLength: (length) => {
set((state) => {
state.gapLength = length;
});
},
setDotRadius: (radius) => {
set((state) => {
state.dotRadius = radius;
});
},
setAisleLength: (length) => {
set((state) => {
state.aisleLength = length;
});
},
setIsFlipped: (isFlipped) => {
set((state) => {
state.isFlipped = isFlipped;
});
},
// Batch setters
setDashedAisleProperties: (width, dashLength, gapLength) => {
set((state) => {
state.aisleType = 'dashed-aisle';
state.aisleWidth = width;
state.dashLength = dashLength;
state.gapLength = gapLength;
});
},
setDottedAisleProperties: (width, dotRadius, gapLength) => {
set((state) => {
state.aisleType = 'dotted-aisle';
state.aisleWidth = width;
state.dotRadius = dotRadius;
state.gapLength = gapLength;
});
},
setArrowsAisleProperties: (width, aisleLength, gapLength) => {
set((state) => {
state.aisleType = 'arrows-aisle';
state.aisleWidth = width;
state.aisleLength = aisleLength;
state.gapLength = gapLength;
});
},
setAisleProperties: (type, width, color) => {
set((state) => {
state.aisleType = type;
state.aisleWidth = width;
state.aisleColor = color;
});
}
}))
);

View File

@@ -0,0 +1,158 @@
import { create } from 'zustand';
import { immer } from 'zustand/middleware/immer';
interface WallStore {
walls: Wall[];
setWalls: (walls: Wall[]) => void;
addWall: (wall: Wall) => void;
updateWall: (uuid: string, updated: Partial<Wall>) => void;
removeWall: (uuid: string) => void;
addDecal: (wallUuid: string, decal: Decal) => void;
updateDecal: (decalUuid: string, decal: Decal) => void;
removeDecal: (decalUuid: string) => void;
updateDecalPosition: (decalUuid: string, position: [number, number, number]) => void;
updateDecalRotation: (decalUuid: string, rotation: number) => void;
updateDecalScale: (decalUuid: string, scale: number) => void;
removePoint: (pointUuid: string) => Wall[];
setPosition: (pointUuid: string, position: [number, number, number]) => void;
setLayer: (pointUuid: string, layer: number) => void;
getWallById: (uuid: string) => Wall | undefined;
getWallPointById: (uuid: string) => Point | undefined;
getConnectedPoints: (uuid: string) => Point[];
}
export const useWallStore = create<WallStore>()(
immer((set, get) => ({
walls: [],
setWalls: (walls) => set((state) => {
state.walls = walls;
}),
addWall: (wall) => set((state) => {
state.walls.push(wall);
}),
updateWall: (uuid, updated) => set((state) => {
const wall = state.walls.find(w => w.wallUuid === uuid);
if (wall) {
Object.assign(wall, updated);
}
}),
removeWall: (uuid) => set((state) => {
state.walls = state.walls.filter(w => w.wallUuid !== uuid);
}),
addDecal: (wallUuid, decal) => set((state) => {
const wallToUpdate = state.walls.find(w => w.wallUuid === wallUuid);
if (wallToUpdate) {
wallToUpdate.decals.push(decal);
}
}),
updateDecal: (decalUuid, decal) => set((state) => {
for (const wall of state.walls) {
const decalToUpdate = wall.decals.find(d => d.decalUuid === decalUuid);
if (decalToUpdate) {
Object.assign(decalToUpdate, decal);
}
}
}),
removeDecal: (decalUuid) => set((state) => {
for (const wall of state.walls) {
wall.decals = wall.decals.filter(d => d.decalUuid !== decalUuid);
}
}),
updateDecalPosition: (decalUuid, position) => set((state) => {
for (const wall of state.walls) {
const decal = wall.decals.find(d => d.decalUuid === decalUuid);
if (decal) {
decal.decalPosition = position;
break;
}
}
}),
updateDecalRotation: (decalUuid, rotation) => set((state) => {
for (const wall of state.walls) {
const decal = wall.decals.find(d => d.decalUuid === decalUuid);
if (decal) {
decal.decalRotation = rotation;
break;
}
}
}),
updateDecalScale: (decalUuid, scale) => set((state) => {
for (const wall of state.walls) {
const decal = wall.decals.find(d => d.decalUuid === decalUuid);
if (decal) {
decal.decalScale = scale;
break;
}
}
}),
removePoint: (pointUuid) => {
const removedWalls: Wall[] = [];
set((state) => {
state.walls = state.walls.filter((wall) => {
const hasPoint = wall.points.some(p => p.pointUuid === pointUuid);
if (hasPoint) {
removedWalls.push(JSON.parse(JSON.stringify(wall)));
return false;
}
return true;
});
});
return removedWalls;
},
setPosition: (pointUuid, position) => set((state) => {
for (const wall of state.walls) {
const point = wall.points.find(p => p.pointUuid === pointUuid);
if (point) {
point.position = position;
}
}
}),
setLayer: (pointUuid, layer) => set((state) => {
for (const wall of state.walls) {
const point = wall.points.find(p => p.pointUuid === pointUuid);
if (point) {
point.layer = layer;
}
}
}),
getWallById: (uuid) => {
return get().walls.find(w => w.wallUuid === uuid);
},
getWallPointById: (uuid) => {
for (const wall of get().walls) {
const point = wall.points.find(p => p.pointUuid === uuid);
if (point) return point;
}
return undefined;
},
getConnectedPoints: (uuid) => {
const connected: Point[] = [];
for (const wall of get().walls) {
for (const point of wall.points) {
if (point.pointUuid === uuid) {
connected.push(...wall.points.filter(p => p.pointUuid !== uuid));
}
}
}
return connected;
},
}))
);

View File

@@ -0,0 +1,37 @@
import { create } from 'zustand';
type Layout = null | 'layout1' | 'layout2' ;
type LayoutState = {
currentLayout: Layout;
setLayout: (layout: Layout) => void;
resetLayout: () => void;
};
const LAYOUT_STORAGE_KEY = 'currentLayout';
const useLayoutStore = create<LayoutState>((set) => ({
currentLayout: (() => {
if (typeof window !== 'undefined') {
const storedLayout = localStorage.getItem(LAYOUT_STORAGE_KEY);
return storedLayout ? (JSON.parse(storedLayout) as Layout) : null;
}
return null;
})(),
setLayout: (layout) => {
if (typeof window !== 'undefined') {
localStorage.setItem(LAYOUT_STORAGE_KEY, JSON.stringify(layout));
}
set({ currentLayout: layout });
},
resetLayout: () => {
if (typeof window !== 'undefined') {
localStorage.removeItem(LAYOUT_STORAGE_KEY);
}
set({ currentLayout: null });
},
}));
export default useLayoutStore;

View File

@@ -0,0 +1,36 @@
import { create } from 'zustand';
interface SelectedUser {
color: string;
name: string;
id: string,
location?: {
position: {
x: number;
y: number;
z: number;
};
rotation?: {
x: number;
y: number;
z: number;
};
target?: {
x: number;
y: number;
z: number;
};
}
}
interface SelectedUserStore {
selectedUser: SelectedUser | null;
setSelectedUser: (user: SelectedUser) => void;
clearSelectedUser: () => void;
}
export const useSelectedUserStore = create<SelectedUserStore>((set) => ({
selectedUser: null,
setSelectedUser: (user) => set({ selectedUser: user }),
clearSelectedUser: () => set({ selectedUser: null }),
}));

View File

@@ -0,0 +1,92 @@
import { create } from 'zustand';
import { immer } from 'zustand/middleware/immer';
interface CommentStore {
comments: CommentsSchema;
// Comment operations
addComment: (comment: CommentSchema) => void;
setComments: (comments: CommentsSchema) => void;
updateComment: (commentId: string, updates: Partial<CommentSchema>) => void;
removeComment: (commentId: string) => void;
// Reply operations
addReply: (commentId: string, reply: Reply) => void;
updateReply: (commentId: string, replyId: string, updates: Partial<Reply>) => void;
removeReply: (commentId: string, replyId: string) => void;
// Getters
getCommentById: (commentId: string) => CommentSchema | undefined;
}
export const useCommentStore = create<CommentStore>()(
immer((set, get) => ({
comments: [],
// Comment operations
addComment: (comment) => {
set((state) => {
if (!state.comments.find(c => c.commentId === comment.commentId)) {
state.comments.push(JSON.parse(JSON.stringify(comment)));
}
});
},
setComments: (comments) => {
set((state) => {
state.comments = comments;
});
},
updateComment: (commentId, updates) => {
set((state) => {
const comment = state.comments.find(c => c.commentId === commentId);
if (comment) {
Object.assign(comment, updates);
}
});
},
removeComment: (commentId) => {
set((state) => {
state.comments = state.comments.filter(c => c.commentId !== commentId);
});
},
// Reply operations
addReply: (commentId, reply) => {
set((state) => {
const comment = state.comments.find(c => c.commentId === commentId);
if (comment) {
comment.replies.push(reply);
}
});
},
updateReply: (commentId, replyId, updates) => {
set((state) => {
const comment = state.comments.find(c => c.commentId === commentId);
if (comment) {
const reply = comment.replies.find(r => r.replyId === replyId);
if (reply) {
Object.assign(reply, updates);
}
}
});
},
removeReply: (commentId, replyId) => {
set((state) => {
const comment = state.comments.find(c => c.commentId === commentId);
if (comment) {
comment.replies = comment.replies.filter(r => r.replyId !== replyId);
}
});
},
// Getter
getCommentById: (commentId) => {
return get().comments.find(c => c.commentId === commentId);
},
}))
);

View File

@@ -0,0 +1,210 @@
import { create } from 'zustand';
import { immer } from 'zustand/middleware/immer';
interface ArmBotStore {
armBots: ArmBotStatus[];
addArmBot: (productUuid: string, event: RoboticArmEventSchema) => void;
removeArmBot: (modelUuid: string) => void;
updateArmBot: (
modelUuid: string,
updates: Partial<Omit<ArmBotStatus, 'modelUuid' | 'productUuid'>>
) => void;
clearArmBots: () => void;
addCurrentAction: (modelUuid: string, actionUuid: string, materialType: string, materialId: string) => void;
removeCurrentAction: (modelUuid: string) => void;
addAction: (modelUuid: string, action: RoboticArmPointSchema['actions'][number]) => void;
removeAction: (modelUuid: string, actionUuid: string) => void;
updateStartPoint: (modelUuid: string, actionUuid: string, startPoint: [number, number, number] | null) => void;
updateEndPoint: (modelUuid: string, actionUuid: string, endPoint: [number, number, number] | null) => void;
setArmBotActive: (modelUuid: string, isActive: boolean) => void;
setArmBotState: (modelUuid: string, newState: ArmBotStatus['state']) => void;
incrementActiveTime: (modelUuid: string, incrementBy: number) => void;
incrementIdleTime: (modelUuid: string, incrementBy: number) => void;
getArmBotById: (modelUuid: string) => ArmBotStatus | undefined;
getArmBotsByProduct: (productUuid: string) => ArmBotStatus[];
getArmBotsByState: (state: string) => ArmBotStatus[];
getActiveArmBots: () => ArmBotStatus[];
getIdleArmBots: () => ArmBotStatus[];
getArmBotsByCurrentAction: (actionUuid: string) => ArmBotStatus[];
}
export const createArmBotStore = () => {
return create<ArmBotStore>()(
immer((set, get) => ({
armBots: [],
addArmBot: (productUuid, event) => {
set((state) => {
const exists = state.armBots.some(a => a.modelUuid === event.modelUuid);
if (!exists) {
state.armBots.push({
...event,
productUuid,
isActive: false,
idleTime: 0,
activeTime: 0,
state: 'idle',
});
}
});
},
removeArmBot: (modelUuid) => {
set((state) => {
state.armBots = state.armBots.filter(a => a.modelUuid !== modelUuid);
});
},
updateArmBot: (modelUuid, updates) => {
set((state) => {
const armBot = state.armBots.find(a => a.modelUuid === modelUuid);
if (armBot) {
Object.assign(armBot, updates);
}
});
},
clearArmBots: () => {
set((state) => {
state.armBots = [];
});
},
addCurrentAction: (modelUuid, actionUuid, materialType, materialId) => {
set((state) => {
const armBot = state.armBots.find(a => a.modelUuid === modelUuid);
if (armBot) {
const action = armBot.point.actions.find(a => a.actionUuid === actionUuid);
if (action) {
armBot.currentAction = {
actionUuid: action.actionUuid,
actionName: action.actionName,
materialType: materialType,
materialId: materialId
};
}
}
});
},
removeCurrentAction: (modelUuid) => {
set((state) => {
const armBot = state.armBots.find(a => a.modelUuid === modelUuid);
if (armBot) {
armBot.currentAction = undefined;
}
});
},
addAction: (modelUuid, action) => {
set((state) => {
const armBot = state.armBots.find(a => a.modelUuid === modelUuid);
if (armBot) {
armBot.point.actions.push(action);
}
});
},
removeAction: (modelUuid, actionUuid) => {
set((state) => {
const armBot = state.armBots.find(a => a.modelUuid === modelUuid);
if (armBot) {
armBot.point.actions = armBot.point.actions.filter(a => a.actionUuid !== actionUuid);
}
});
},
updateStartPoint: (modelUuid, actionUuid, startPoint) => {
set((state) => {
const armBot = state.armBots.find(a => a.modelUuid === modelUuid);
if (armBot) {
const action = armBot.point.actions.find(a => a.actionUuid === actionUuid);
if (action) {
action.process.startPoint = startPoint;
}
}
});
},
updateEndPoint: (modelUuid, actionUuid, endPoint) => {
set((state) => {
const armBot = state.armBots.find(a => a.modelUuid === modelUuid);
if (armBot) {
const action = armBot.point.actions.find(a => a.actionUuid === actionUuid);
if (action) {
action.process.endPoint = endPoint;
}
}
});
},
setArmBotActive: (modelUuid, isActive) => {
set((state) => {
const armBot = state.armBots.find(a => a.modelUuid === modelUuid);
if (armBot) {
armBot.isActive = isActive;
}
});
},
setArmBotState: (modelUuid, newState) => {
set((state) => {
const armBot = state.armBots.find(a => a.modelUuid === modelUuid);
if (armBot) {
armBot.state = newState;
}
});
},
incrementActiveTime: (modelUuid, incrementBy) => {
set((state) => {
const armBot = state.armBots.find(a => a.modelUuid === modelUuid);
if (armBot) {
armBot.activeTime += incrementBy;
}
});
},
incrementIdleTime: (modelUuid, incrementBy) => {
set((state) => {
const armBot = state.armBots.find(a => a.modelUuid === modelUuid);
if (armBot) {
armBot.idleTime += incrementBy;
}
});
},
getArmBotById: (modelUuid) => {
return get().armBots.find(a => a.modelUuid === modelUuid);
},
getArmBotsByProduct: (productUuid) => {
return get().armBots.filter(a => a.productUuid === productUuid);
},
getArmBotsByState: (state) => {
return get().armBots.filter(a => a.state === state);
},
getActiveArmBots: () => {
return get().armBots.filter(a => a.isActive);
},
getIdleArmBots: () => {
return get().armBots.filter(a => !a.isActive && a.state === 'idle');
},
getArmBotsByCurrentAction: (actionUuid) => {
return get().armBots.filter(a => a.currentAction?.actionUuid === actionUuid);
}
}))
)
}
export type ArmBotStoreType = ReturnType<typeof createArmBotStore>;

View File

@@ -0,0 +1,140 @@
import { create } from 'zustand';
import { immer } from 'zustand/middleware/immer';
interface ConveyorStore {
conveyors: ConveyorStatus[];
addConveyor: (productUuid: string, event: ConveyorEventSchema) => void;
removeConveyor: (modelUuid: string) => void;
updateConveyor: (
modelUuid: string,
updates: Partial<Omit<ConveyorStatus, 'modelUuid' | 'productUuid'>>
) => void;
clearConveyors: () => void;
setConveyorActive: (modelUuid: string, isActive: boolean) => void;
setConveyorState: (modelUuid: string, newState: ConveyorStatus['state']) => void;
setConveyorPaused: (modelUuid: string, isPaused: boolean) => void;
incrementActiveTime: (modelUuid: string, incrementBy: number) => void;
incrementIdleTime: (modelUuid: string, incrementBy: number) => void;
getConveyorById: (modelUuid: string) => ConveyorStatus | undefined;
getConveyorsByProduct: (productUuid: string) => ConveyorStatus[];
getConveyorsByState: (state: string) => ConveyorStatus[];
getActiveConveyors: () => ConveyorStatus[];
getIdleConveyors: () => ConveyorStatus[];
}
export const createConveyorStore = () => {
return create<ConveyorStore>()(
immer((set, get) => ({
conveyors: [],
addConveyor: (productUuid, event) => {
set((state) => {
const exists = state.conveyors.some(c => c.modelUuid === event.modelUuid);
if (!exists) {
state.conveyors.push({
...event,
productUuid,
isActive: false,
isPaused: false,
idleTime: 0,
activeTime: 0,
state: 'idle',
});
}
});
},
removeConveyor: (modelUuid) => {
set((state) => {
state.conveyors = state.conveyors.filter(c => c.modelUuid !== modelUuid);
});
},
updateConveyor: (modelUuid, updates) => {
set((state) => {
const conveyor = state.conveyors.find(c => c.modelUuid === modelUuid);
if (conveyor) {
Object.assign(conveyor, updates);
}
});
},
clearConveyors: () => {
set((state) => {
state.conveyors = [];
});
},
setConveyorActive: (modelUuid, isActive) => {
set((state) => {
const conveyor = state.conveyors.find(c => c.modelUuid === modelUuid);
if (conveyor) {
conveyor.isActive = isActive;
}
});
},
setConveyorState: (modelUuid, newState) => {
set((state) => {
const conveyor = state.conveyors.find(c => c.modelUuid === modelUuid);
if (conveyor) {
conveyor.state = newState;
}
});
},
setConveyorPaused: (modelUuid, isPaused) => {
set((state) => {
const conveyor = state.conveyors.find(c => c.modelUuid === modelUuid);
if (conveyor) {
conveyor.isPaused = isPaused;
}
});
},
incrementActiveTime: (modelUuid, incrementBy) => {
set((state) => {
const conveyor = state.conveyors.find(c => c.modelUuid === modelUuid);
if (conveyor) {
conveyor.activeTime += incrementBy;
}
});
},
incrementIdleTime: (modelUuid, incrementBy) => {
set((state) => {
const conveyor = state.conveyors.find(c => c.modelUuid === modelUuid);
if (conveyor) {
conveyor.idleTime += incrementBy;
}
});
},
getConveyorById: (modelUuid) => {
return get().conveyors.find(c => c.modelUuid === modelUuid);
},
getConveyorsByProduct: (productUuid) => {
return get().conveyors.filter(c => c.productUuid === productUuid);
},
getConveyorsByState: (state) => {
return get().conveyors.filter(c => c.state === state);
},
getActiveConveyors: () => {
return get().conveyors.filter(c => c.isActive);
},
getIdleConveyors: () => {
return get().conveyors.filter(c => !c.isActive && c.state === 'idle');
},
}))
)
}
export type ConveyorStoreType = ReturnType<typeof createConveyorStore>;

View File

@@ -0,0 +1,350 @@
import { create } from 'zustand';
import { immer } from 'zustand/middleware/immer';
type EventsStore = {
events: EventsSchema[];
// Event-level actions
addEvent: (event: EventsSchema) => void;
removeEvent: (modelUuid: string) => void;
updateEvent: (modelUuid: string, updates: Partial<EventsSchema>) => EventsSchema | undefined;
// Point-level actions
addPoint: (modelUuid: string, point: ConveyorPointSchema | VehiclePointSchema | RoboticArmPointSchema | MachinePointSchema | StoragePointSchema) => void;
removePoint: (modelUuid: string, pointUuid: string) => void;
updatePoint: (
modelUuid: string,
pointUuid: string,
updates: Partial<ConveyorPointSchema | VehiclePointSchema | RoboticArmPointSchema | MachinePointSchema | StoragePointSchema>
) => EventsSchema | undefined;
// Action-level actions
addAction: (
modelUuid: string,
pointUuid: string,
action: ConveyorPointSchema['action'] | VehiclePointSchema['action'] | RoboticArmPointSchema['actions'][0] | MachinePointSchema['action'] | StoragePointSchema['action']
) => void;
removeAction: (actionUuid: string) => void;
updateAction: (
actionUuid: string,
updates: Partial<ConveyorPointSchema['action'] | VehiclePointSchema['action'] | RoboticArmPointSchema['actions'][0] | MachinePointSchema['action'] | StoragePointSchema['action']>
) => void;
// Trigger-level actions
addTrigger: (actionUuid: string, trigger: TriggerSchema) => void;
removeTrigger: (triggerUuid: string) => void;
updateTrigger: (triggerUuid: string, updates: Partial<TriggerSchema>) => void;
// Helper functions
getEventByModelUuid: (modelUuid: string) => EventsSchema | 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;
};
export const useEventsStore = create<EventsStore>()(
immer((set, get) => ({
events: [],
// Event-level actions
addEvent: (event) => {
set((state) => {
if (!state.events.some(e => 'modelUuid' in e && e.modelUuid === event.modelUuid)) {
state.events.push(event);
}
});
},
removeEvent: (modelUuid) => {
set((state) => {
state.events = state.events.filter(e => 'modelUuid' in e && e.modelUuid !== modelUuid);
});
},
updateEvent: (modelUuid, updates) => {
let updatedEvent: EventsSchema | undefined;
set((state) => {
const event = state.events.find(e => 'modelUuid' in e && e.modelUuid === modelUuid);
if (event) {
Object.assign(event, updates);
updatedEvent = JSON.parse(JSON.stringify(event));
}
});
return updatedEvent;
},
// Point-level actions
addPoint: (modelUuid, point) => {
set((state) => {
const event = state.events.find(e => 'modelUuid' in e && e.modelUuid === modelUuid);
if (event && 'points' in event) {
const existingPoint = (event as ConveyorEventSchema).points.find(p => p.uuid === point.uuid);
if (!existingPoint) {
(event as ConveyorEventSchema).points.push(point as ConveyorPointSchema);
}
} else if (event && 'point' in event) {
if (!(event as any).point || (event as any).point.uuid !== point.uuid) {
(event as VehicleEventSchema | RoboticArmEventSchema | MachineEventSchema | StorageEventSchema).point = point as any;
}
}
});
},
removePoint: (modelUuid, pointUuid) => {
set((state) => {
const event = state.events.find(e => 'modelUuid' in e && e.modelUuid === modelUuid);
if (event && 'points' in event) {
(event as ConveyorEventSchema).points = (event as ConveyorEventSchema).points.filter(p => p.uuid !== pointUuid);
}
// For single-point events, you might want to handle differently
});
},
updatePoint: (modelUuid, pointUuid, updates) => {
let updatedEvent: EventsSchema | undefined;
set((state) => {
const event = state.events.find(e => 'modelUuid' in e && e.modelUuid === modelUuid);
if (event && 'points' in event) {
const point = (event as ConveyorEventSchema).points.find(p => p.uuid === pointUuid);
if (point) {
Object.assign(point, updates);
updatedEvent = JSON.parse(JSON.stringify(event));
}
} else if (event && 'point' in event && (event as any).point.uuid === pointUuid) {
Object.assign((event as any).point, updates);
updatedEvent = JSON.parse(JSON.stringify(event));
}
});
return updatedEvent;
},
// Action-level actions
addAction: (modelUuid, pointUuid, action) => {
set((state) => {
const event = state.events.find(e => 'modelUuid' in e && e.modelUuid === modelUuid);
if (event && 'points' in event) {
const point = (event as ConveyorEventSchema).points.find(p => p.uuid === pointUuid);
if (point && (!point.action || point.action.actionUuid !== action.actionUuid)) {
point.action = action as any;
}
} else if (event && 'point' in event && (event as any).point.uuid === pointUuid) {
const point = (event as any).point;
if ('action' in point && (!point.action || point.action.actionUuid !== action.actionUuid)) {
point.action = action;
} else if ('actions' in point && !point.actions.some((a: any) => a.actionUuid === action.actionUuid)) {
point.actions.push(action);
}
}
});
},
removeAction: (actionUuid) => {
set((state) => {
for (const event of state.events) {
if ('points' in event) {
for (const point of (event as ConveyorEventSchema).points) {
if (point.action && point.action.actionUuid === actionUuid) {
// Handle removal for single action points
}
}
} else if ('point' in event) {
const point = (event as any).point;
if (event.type === "roboticArm") {
if ('actions' in point) {
point.actions = point.actions.filter((a: any) => a.actionUuid !== actionUuid);
}
} else if ('action' in point && point.action?.actionUuid === actionUuid) {
// Handle single action
}
}
}
});
},
updateAction: (actionUuid, updates) => {
set((state) => {
for (const event of state.events) {
if ('points' in event) {
for (const point of (event as ConveyorEventSchema).points) {
if (point.action && point.action.actionUuid === actionUuid) {
Object.assign(point.action, updates);
return;
}
}
} else if ('point' in event) {
const point = (event as any).point;
if ('action' in point && point.action.actionUuid === actionUuid) {
Object.assign(point.action, updates);
return;
} else if ('actions' in point) {
const action = point.actions.find((a: any) => a.actionUuid === actionUuid);
if (action) {
Object.assign(action, updates);
return;
}
}
}
}
});
},
// Trigger-level actions
addTrigger: (actionUuid, trigger) => {
set((state) => {
for (const event of state.events) {
if ('points' in event) {
for (const point of (event as ConveyorEventSchema).points) {
if (point.action && point.action.actionUuid === actionUuid) {
if (!point.action.triggers.some(t => t.triggerUuid === trigger.triggerUuid)) {
point.action.triggers.push(trigger);
}
return;
}
}
} else if ('point' in event) {
const point: MachinePointSchema | VehiclePointSchema = (event as any).point;
if ('action' in point && point.action.actionUuid === actionUuid) {
if (!point.action.triggers.some(t => t.triggerUuid === trigger.triggerUuid)) {
point.action.triggers.push(trigger);
}
return;
} else if ('actions' in point) {
const action = (point as RoboticArmPointSchema).actions.find((a) => a.actionUuid === actionUuid);
if (action && !action.triggers.some(t => t.triggerUuid === trigger.triggerUuid)) {
action.triggers.push(trigger);
return;
}
}
}
}
});
},
removeTrigger: (triggerUuid) => {
set((state) => {
for (const event of state.events) {
if ('points' in event) {
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);
}
}
} else if ('point' in event) {
const point = (event as any).point;
if ('action' in point && 'triggers' in point.action) {
point.action.triggers = point.action.triggers.filter((t: any) => t.triggerUuid !== triggerUuid);
} else if ('actions' in point) {
for (const action of point.actions) {
if ('triggers' in action) {
action.triggers = action.triggers.filter((t: any) => t.triggerUuid !== triggerUuid);
}
}
}
}
}
});
},
updateTrigger: (triggerUuid, updates) => {
set((state) => {
for (const event of state.events) {
if ('points' in event) {
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) {
Object.assign(trigger, updates);
return;
}
}
}
} else if ('point' in event) {
const point = (event as any).point;
if ('action' in point && 'triggers' in point.action) {
const trigger = point.action.triggers.find((t: any) => t.triggerUuid === triggerUuid);
if (trigger) {
Object.assign(trigger, updates);
return;
}
} else if ('actions' in point) {
for (const action of point.actions) {
if ('triggers' in action) {
const trigger = action.triggers.find((t: any) => t.triggerUuid === triggerUuid);
if (trigger) {
Object.assign(trigger, updates);
return;
}
}
}
}
}
}
});
},
// Helper functions
getEventByModelUuid: (modelUuid) => {
return get().events.find(e => 'modelUuid' in e && e.modelUuid === modelUuid);
},
getPointByUuid: (modelUuid, pointUuid) => {
const event = get().events.find(e => 'modelUuid' in e && e.modelUuid === modelUuid);
if (event && 'points' in event) {
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;
}
return undefined;
},
getActionByUuid: (actionUuid) => {
const state = get();
for (const event of state.events) {
if ('points' in event) {
for (const point of (event as ConveyorEventSchema).points) {
if (point.action && point.action.actionUuid === actionUuid) {
return point.action;
}
}
} else if ('point' in event) {
const point = (event as any).point;
if ('action' in point && point.action.actionUuid === actionUuid) {
return point.action;
} else if ('actions' in point) {
const action = point.actions.find((a: any) => a.actionUuid === actionUuid);
if (action) return action;
}
}
}
return undefined;
},
getTriggerByUuid: (triggerUuid) => {
const state = get();
for (const event of state.events) {
if ('points' in event) {
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;
}
}
} else if ('point' in event) {
const point = (event as any).point;
if ('action' in point && 'triggers' in point.action) {
const trigger = point.action.triggers.find((t: any) => t.triggerUuid === triggerUuid);
if (trigger) return trigger;
} else if ('actions' in point) {
for (const action of point.actions) {
if ('triggers' in action) {
const trigger = action.triggers.find((t: any) => t.triggerUuid === triggerUuid);
if (trigger) return trigger;
}
}
}
}
}
return undefined;
}
}))
);

View File

@@ -0,0 +1,180 @@
import { create } from "zustand";
import { immer } from "zustand/middleware/immer";
interface MachineStore {
machines: MachineStatus[];
addMachine: (productUuid: string, machine: MachineEventSchema) => void;
removeMachine: (modelUuid: string) => void;
updateMachine: (
modelUuid: string,
updates: Partial<Omit<MachineStatus, "modelUuid" | "productUuid">>
) => void;
clearMachines: () => void;
addCurrentAction: (
modelUuid: string,
actionUuid: string,
materialType: string,
materialId: string
) => void;
removeCurrentAction: (modelUuid: string) => void;
setMachineActive: (modelUuid: string, isActive: boolean) => void;
setMachineState: (
modelUuid: string,
newState: MachineStatus["state"]
) => void;
incrementActiveTime: (modelUuid: string, incrementBy: number) => void;
incrementIdleTime: (modelUuid: string, incrementBy: number) => void;
resetTime: (modelUuid: string) => void;
getMachineById: (modelUuid: string) => MachineStatus | undefined;
getMachinesByProduct: (productUuid: string) => MachineStatus[];
getMachinesBystate: (state: string) => MachineStatus[];
getActiveMachines: () => MachineStatus[];
getIdleMachines: () => MachineStatus[];
}
export const createMachineStore = () => {
return create<MachineStore>()(
immer((set, get) => ({
machines: [],
addMachine: (productUuid, machine) => {
set((state) => {
const exists = state.machines.some(
(m) => m.modelUuid === machine.modelUuid
);
if (!exists) {
state.machines.push({
...machine,
productUuid,
isActive: false,
idleTime: 0,
activeTime: 0,
state: "idle",
});
}
});
},
removeMachine: (modelUuid) => {
set((state) => {
state.machines = state.machines.filter(
(m) => m.modelUuid !== modelUuid
);
});
},
updateMachine: (modelUuid, updates) => {
set((state) => {
const machine = state.machines.find((m) => m.modelUuid === modelUuid);
if (machine) {
Object.assign(machine, updates);
}
});
},
clearMachines: () => {
set((state) => {
state.machines = [];
});
},
addCurrentAction: (modelUuid, actionUuid, materialType, materialId) => {
set((state) => {
const armBot = state.machines.find((a) => a.modelUuid === modelUuid);
if (armBot) {
const action = armBot.point.action;
if (action) {
armBot.currentAction = {
actionUuid: actionUuid,
actionName: action.actionName,
materialType: materialType,
materialId: materialId,
};
}
}
});
},
removeCurrentAction: (modelUuid) => {
set((state) => {
const armBot = state.machines.find((a) => a.modelUuid === modelUuid);
if (armBot) {
armBot.currentAction = undefined;
}
});
},
setMachineActive: (modelUuid, isActive) => {
set((state) => {
const machine = state.machines.find((m) => m.modelUuid === modelUuid);
if (machine) {
machine.isActive = isActive;
}
});
},
setMachineState: (modelUuid, newState) => {
set((state) => {
const machine = state.machines.find((m) => m.modelUuid === modelUuid);
if (machine) {
machine.state = newState;
}
});
},
incrementActiveTime: (modelUuid, incrementBy) => {
set((state) => {
const machine = state.machines.find((m) => m.modelUuid === modelUuid);
if (machine) {
machine.activeTime += incrementBy;
}
});
},
incrementIdleTime: (modelUuid, incrementBy) => {
set((state) => {
const machine = state.machines.find((m) => m.modelUuid === modelUuid);
if (machine) {
machine.idleTime += incrementBy;
}
});
},
resetTime: (modelUuid) => {
set((state) => {
const machine = state.machines.find((m) => m.modelUuid === modelUuid);
if (machine) {
machine.activeTime = 0;
machine.idleTime = 0;
}
});
},
getMachineById: (modelUuid) => {
return get().machines.find((m) => m.modelUuid === modelUuid);
},
getMachinesByProduct: (productUuid) => {
return get().machines.filter((m) => m.productUuid === productUuid);
},
getMachinesBystate: (state) => {
return get().machines.filter((m) => m.state === state);
},
getActiveMachines: () => {
return get().machines.filter((m) => m.isActive);
},
getIdleMachines: () => {
return get().machines.filter((m) => !m.isActive && m.state === "idle");
},
}))
)
}
export type MachineStoreType = ReturnType<typeof createMachineStore>;

View File

@@ -0,0 +1,284 @@
import { create } from 'zustand';
import { immer } from 'zustand/middleware/immer';
type MaterialsStore = {
materials: MaterialsSchema;
materialHistory: MaterialHistorySchema;
addMaterial: (material: MaterialSchema) => MaterialSchema | undefined;
removeMaterial: (materialId: string) => MaterialSchema | undefined;
clearMaterials: () => void;
updateMaterial: (materialId: string, updates: Partial<MaterialSchema>) => MaterialSchema | undefined;
setPreviousLocation: (
materialId: string,
location: {
modelUuid: string;
pointUuid: string;
actionUuid: string;
}
) => MaterialSchema | undefined;
setCurrentLocation: (
materialId: string,
location: {
modelUuid: string;
pointUuid: string;
actionUuid: string;
}
) => MaterialSchema | undefined;
setNextLocation: (
materialId: string,
location: {
modelUuid: string;
pointUuid: string;
} | null
) => MaterialSchema | undefined;
setMaterial: (materialId: string, materialType: string) => MaterialSchema | undefined;
setStartTime: (materialId: string, startTime: number) => MaterialSchema | undefined;
setEndTime: (materialId: string, endTime: number) => MaterialSchema | undefined;
setCost: (materialId: string, cost: number) => MaterialSchema | undefined;
setWeight: (materialId: string, weight: number) => MaterialSchema | undefined;
setIsActive: (materialId: string, isActive: boolean) => MaterialSchema | undefined;
setIsVisible: (materialId: string, isVisible: boolean) => MaterialSchema | undefined;
setIsPaused: (materialId: string, isPaused: boolean) => MaterialSchema | undefined;
setIsRendered: (materialId: string, isRendered: boolean) => MaterialSchema | undefined;
getMaterialById: (materialId: string) => MaterialSchema | undefined;
getMaterialsByCurrentModelUuid: (currentModelUuid: string) => MaterialSchema[] | undefined;
getMaterialByCurrentPointUuid: (currentPointUuid: string) => MaterialSchema | undefined;
getMaterialsByPoint: (pointUuid: string) => MaterialSchema[];
getMaterialsByModel: (modelUuid: string) => MaterialSchema[];
getMaterialHistory: () => MaterialHistorySchema;
};
export const createMaterialStore = () => {
return create<MaterialsStore>()(
immer((set, get) => ({
materials: [],
materialHistory: [],
addMaterial: (material) => {
let updatedMaterial: MaterialSchema | undefined;
set((state) => {
state.materials.push(material);
});
return updatedMaterial;
},
removeMaterial: (materialId) => {
let updatedMaterial: MaterialSchema | undefined;
set((state) => {
const material = state.materials.find(m => m.materialId === materialId);
if (material) {
state.materials = state.materials.filter(m => m.materialId !== materialId);
updatedMaterial = JSON.parse(JSON.stringify(material));
state.materialHistory.push({
material,
removedAt: new Date().toISOString()
});
}
});
return updatedMaterial;
},
clearMaterials: () => {
set((state) => {
state.materials = [];
});
},
updateMaterial: (materialId, updates) => {
let updatedMaterial: MaterialSchema | undefined;
set((state) => {
const material = state.materials.find(m => m.materialId === materialId);
if (material) {
Object.assign(material, updates);
updatedMaterial = JSON.parse(JSON.stringify(material));
}
});
return updatedMaterial;
},
setPreviousLocation: (materialId, location) => {
let updatedMaterial: MaterialSchema | undefined;
set((state) => {
const material = state.materials.find(m => m.materialId === materialId);
if (material) {
material.previous = location;
updatedMaterial = JSON.parse(JSON.stringify(material));
}
});
return updatedMaterial;
},
setCurrentLocation: (materialId, location) => {
let updatedMaterial: MaterialSchema | undefined;
set((state) => {
const material = state.materials.find(m => m.materialId === materialId);
if (material) {
material.current = location;
updatedMaterial = JSON.parse(JSON.stringify(material));
}
});
return updatedMaterial;
},
setNextLocation: (materialId, location) => {
let updatedMaterial: MaterialSchema | undefined;
set((state) => {
const material = state.materials.find(m => m.materialId === materialId);
if (material) {
material.next = location;
updatedMaterial = JSON.parse(JSON.stringify(material));
}
});
return updatedMaterial;
},
setMaterial: (materialId, materialType) => {
let updatedMaterial: MaterialSchema | undefined;
set((state) => {
const material = state.materials.find(m => m.materialId === materialId);
if (material) {
material.materialType = materialType;
updatedMaterial = JSON.parse(JSON.stringify(material));
};
});
return updatedMaterial;
},
setStartTime: (materialId, startTime) => {
let updatedMaterial: MaterialSchema | undefined;
set((state) => {
const material = state.materials.find(m => m.materialId === materialId);
if (material) {
material.startTime = startTime
updatedMaterial = JSON.parse(JSON.stringify(material));
};
});
return updatedMaterial;
},
setEndTime: (materialId, endTime) => {
let updatedMaterial: MaterialSchema | undefined;
set((state) => {
const material = state.materials.find(m => m.materialId === materialId);
if (material) {
material.endTime = endTime;
updatedMaterial = JSON.parse(JSON.stringify(material));
};
});
return updatedMaterial;
},
setCost: (materialId, cost) => {
let updatedMaterial: MaterialSchema | undefined;
set((state) => {
const material = state.materials.find(m => m.materialId === materialId);
if (material) {
material.cost = cost;
updatedMaterial = JSON.parse(JSON.stringify(material));
};
});
return updatedMaterial;
},
setWeight: (materialId, weight) => {
let updatedMaterial: MaterialSchema | undefined;
set((state) => {
const material = state.materials.find(m => m.materialId === materialId);
if (material) {
material.weight = weight;
updatedMaterial = JSON.parse(JSON.stringify(material));
};
});
return updatedMaterial;
},
setIsActive: (materialId, isActive) => {
let updatedMaterial: MaterialSchema | undefined;
set((state) => {
const material = state.materials.find(m => m.materialId === materialId);
if (material) {
material.isActive = isActive;
updatedMaterial = JSON.parse(JSON.stringify(material));
};
});
return updatedMaterial;
},
setIsVisible: (materialId, isVisible) => {
let updatedMaterial: MaterialSchema | undefined;
set((state) => {
const material = state.materials.find(m => m.materialId === materialId);
if (material) {
material.isVisible = isVisible;
updatedMaterial = JSON.parse(JSON.stringify(material));
};
});
return updatedMaterial;
},
setIsPaused: (materialId, isPaused) => {
let updatedMaterial: MaterialSchema | undefined;
set((state) => {
const material = state.materials.find(m => m.materialId === materialId);
if (material) {
material.isPaused = isPaused;
updatedMaterial = JSON.parse(JSON.stringify(material));
};
});
return updatedMaterial;
},
setIsRendered: (materialId, isRendered) => {
let updatedMaterial: MaterialSchema | undefined;
set((state) => {
const material = state.materials.find(m => m.materialId === materialId);
if (material) {
material.isRendered = isRendered;
updatedMaterial = JSON.parse(JSON.stringify(material));
};
});
return updatedMaterial;
},
getMaterialById: (materialId) => {
return get().materials.find(m => m.materialId === materialId);
},
getMaterialsByCurrentModelUuid: (currentModelUuid) => {
return get().materials.filter(m => m.current?.modelUuid === currentModelUuid);
},
getMaterialByCurrentPointUuid: (currentPointlUuid) => {
return get().materials.find(m => m.current?.pointUuid === currentPointlUuid);
},
getMaterialsByPoint: (pointUuid) => {
return get().materials.filter(m =>
m.current?.pointUuid === pointUuid ||
m.next?.pointUuid === pointUuid
);
},
getMaterialsByModel: (modelUuid) => {
return get().materials.filter(m =>
m.current?.modelUuid === modelUuid ||
m.next?.modelUuid === modelUuid
);
},
getMaterialHistory: () => {
return get().materialHistory;
},
}))
)
}
export type MaterialStoreType = ReturnType<typeof createMaterialStore>;

View File

@@ -0,0 +1,791 @@
import { create } from 'zustand';
import { immer } from 'zustand/middleware/immer';
type ProductsStore = {
products: productsSchema;
// Product-level actions
addProduct: (productName: string, productUuid: string) => void;
setProducts: (products: productsSchema) => void;
removeProduct: (productUuid: string) => void;
updateProduct: (productUuid: string, updates: Partial<{ productName: string; eventDatas: EventsSchema[] }>) => void;
// Event-level actions
addEvent: (productUuid: string, event: EventsSchema) => void;
removeEvent: (productUuid: string, modelUuid: string) => void;
deleteEvent: (modelUuid: string) => void;
updateEvent: (productUuid: string, modelUuid: string, updates: Partial<EventsSchema>) => EventsSchema | undefined;
// Point-level actions
addPoint: (productUuid: string, modelUuid: string, point: ConveyorPointSchema | VehiclePointSchema | RoboticArmPointSchema | MachinePointSchema | StoragePointSchema) => void;
removePoint: (productUuid: string, modelUuid: string, pointUuid: string) => void;
updatePoint: (
productUuid: string,
modelUuid: string,
pointUuid: string,
updates: Partial<ConveyorPointSchema | VehiclePointSchema | RoboticArmPointSchema | MachinePointSchema | StoragePointSchema>
) => EventsSchema | undefined;
// Action-level actions
addAction: (
productUuid: string,
modelUuid: string,
pointUuid: string,
action: ConveyorPointSchema['action'] | VehiclePointSchema['action'] | RoboticArmPointSchema['actions'][0] | MachinePointSchema['action'] | StoragePointSchema['action']
) => EventsSchema | undefined;
removeAction: (productUuid: string, actionUuid: string) => EventsSchema | undefined;
updateAction: (
productUuid: string,
actionUuid: string,
updates: Partial<ConveyorPointSchema['action'] | VehiclePointSchema['action'] | RoboticArmPointSchema['actions'][0] | MachinePointSchema['action'] | StoragePointSchema['action']>
) => EventsSchema | undefined;
// Trigger-level actionss
addTrigger: (
productUuid: string,
actionUuid: string,
trigger: TriggerSchema
) => EventsSchema | undefined;
removeTrigger: (productUuid: string, triggerUuid: string) => EventsSchema | undefined;
updateTrigger: (
productUuid: string,
triggerUuid: string,
updates: Partial<TriggerSchema>
) => EventsSchema | undefined;
// Renaming functions
renameProduct: (productUuid: string, newName: string) => void;
renameAction: (productUuid: string, actionUuid: string, newName: string) => EventsSchema | undefined;
renameTrigger: (productUuid: string, triggerUuid: string, newName: string) => EventsSchema | undefined;
// Helper functions
getProductById: (productUuid: string) => { productName: string; productUuid: string; eventDatas: EventsSchema[] } | undefined;
getEventByModelUuid: (productUuid: string, modelUuid: string) => EventsSchema | undefined;
getEventByActionUuid: (productUuid: string, actionUuid: string) => EventsSchema | undefined;
getEventByTriggerUuid: (productUuid: string, triggerUuid: string) => EventsSchema | undefined;
getEventByPointUuid: (productUuid: string, pointUuid: string) => EventsSchema | undefined;
getPointByUuid: (productUuid: string, modelUuid: string, pointUuid: string) => ConveyorPointSchema | VehiclePointSchema | RoboticArmPointSchema | MachinePointSchema | StoragePointSchema | undefined;
getActionByUuid: (productUuid: string, actionUuid: string) => (ConveyorPointSchema['action'] | VehiclePointSchema['action'] | RoboticArmPointSchema['actions'][0] | MachinePointSchema['action'] | StoragePointSchema['action']) | undefined;
getActionByPointUuid: (productUuid: string, pointUuid: string) => (ConveyorPointSchema['action'] | VehiclePointSchema['action'] | RoboticArmPointSchema['actions'][0] | MachinePointSchema['action'] | StoragePointSchema['action']) | undefined;
getModelUuidByPointUuid: (productUuid: string, actionUuid: string) => (string) | undefined;
getModelUuidByActionUuid: (productUuid: string, actionUuid: string) => (string) | undefined;
getPointUuidByActionUuid: (productUuid: string, actionUuid: string) => (string) | undefined;
getTriggerByUuid: (productUuid: string, triggerUuid: string) => TriggerSchema | undefined;
getIsEventInProduct: (productUuid: string, modelUuid: string) => boolean;
};
export const useProductStore = create<ProductsStore>()(
immer((set, get) => ({
products: [],
// Product-level actions
addProduct: (productName, productUuid) => {
set((state) => {
const existingProduct = state.products.find(p => p.productUuid === productUuid);
if (!existingProduct) {
const newProduct = {
productName,
productUuid: productUuid,
eventDatas: []
};
state.products.push(newProduct);
}
});
},
setProducts: (products) => {
set((state) => {
state.products = products;
});
},
removeProduct: (productUuid) => {
set((state) => {
state.products = state.products.filter(p => p.productUuid !== productUuid);
});
},
updateProduct: (productUuid, updates) => {
set((state) => {
const product = state.products.find(p => p.productUuid === productUuid);
if (product) {
Object.assign(product, updates);
}
});
},
// Event-level actions
addEvent: (productUuid, event) => {
set((state) => {
const product = state.products.find(p => p.productUuid === productUuid);
if (product) {
const existingEvent = product.eventDatas.find(e => 'modelUuid' in e && e.modelUuid === event.modelUuid);
if (!existingEvent) {
product.eventDatas.push(event);
}
}
});
},
removeEvent: (productUuid, modelUuid) => {
set((state) => {
const product = state.products.find(p => p.productUuid === productUuid);
if (product) {
product.eventDatas = product.eventDatas.filter(e => 'modelUuid' in e && e.modelUuid !== modelUuid);
}
});
},
deleteEvent: (modelUuid) => {
set((state) => {
for (const product of state.products) {
product.eventDatas = product.eventDatas.filter(e => 'modelUuid' in e && e.modelUuid !== modelUuid);
}
});
},
updateEvent: (productUuid, modelUuid, updates) => {
let updatedEvent: EventsSchema | undefined;
set((state) => {
const product = state.products.find(p => p.productUuid === productUuid);
if (product) {
const event = product.eventDatas.find(e => 'modelUuid' in e && e.modelUuid === modelUuid);
if (event) {
Object.assign(event, updates);
updatedEvent = JSON.parse(JSON.stringify(event));
}
}
});
return updatedEvent;
},
// Point-level actions
addPoint: (productUuid, modelUuid, point) => {
set((state) => {
const product = state.products.find(p => p.productUuid === productUuid);
if (product) {
const event = product.eventDatas.find(e => 'modelUuid' in e && e.modelUuid === modelUuid);
if (event && 'points' in event) {
const existingPoint = (event as ConveyorEventSchema).points.find(p => p.uuid === point.uuid);
if (!existingPoint) {
(event as ConveyorEventSchema).points.push(point as ConveyorPointSchema);
}
} else if (event && 'point' in event) {
const existingPoint = (event as any).point?.uuid === point.uuid;
if (!existingPoint) {
(event as VehicleEventSchema | RoboticArmEventSchema | MachineEventSchema | StorageEventSchema).point = point as any;
}
}
}
});
},
removePoint: (productUuid, modelUuid, pointUuid) => {
set((state) => {
const product = state.products.find(p => p.productUuid === productUuid);
if (product) {
const event = product.eventDatas.find(e => 'modelUuid' in e && e.modelUuid === modelUuid);
if (event && 'points' in event) {
(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
}
}
});
},
updatePoint: (productUuid, modelUuid, pointUuid, updates) => {
let updatedEvent: EventsSchema | undefined;
set((state) => {
const product = state.products.find(p => p.productUuid === productUuid);
if (product) {
const event = product.eventDatas.find(e => 'modelUuid' in e && e.modelUuid === modelUuid);
if (event && 'points' in event) {
const point = (event as ConveyorEventSchema).points.find(p => p.uuid === pointUuid);
if (point) {
Object.assign(point, updates);
updatedEvent = JSON.parse(JSON.stringify(event));
}
} else if (event && 'point' in event && (event as any).point.uuid === pointUuid) {
Object.assign((event as any).point, updates);
updatedEvent = JSON.parse(JSON.stringify(event));
}
}
});
return updatedEvent;
},
// Action-level actions
addAction: (productUuid, modelUuid, pointUuid, action) => {
let updatedEvent: EventsSchema | undefined;
set((state) => {
const product = state.products.find(p => p.productUuid === productUuid);
if (product) {
const event = product.eventDatas.find(e => 'modelUuid' in e && e.modelUuid === modelUuid);
if (event && 'points' in event) {
const point = (event as ConveyorEventSchema).points.find(p => p.uuid === pointUuid);
if (point && (!point.action || point.action.actionUuid !== action.actionUuid)) {
point.action = action as any;
updatedEvent = JSON.parse(JSON.stringify(event));
}
} else if (event && 'point' in event && (event as any).point.uuid === pointUuid) {
if ('action' in (event as any).point) {
if (!(event as any).point.action || (event as any).point.action.actionUuid !== action.actionUuid) {
(event as any).point.action = action;
updatedEvent = JSON.parse(JSON.stringify(event));
}
} else if ('actions' in (event as any).point) {
const existingAction = (event as any).point.actions.find((a: any) => a.actionUuid === action.actionUuid);
if (!existingAction) {
(event as any).point.actions.push(action);
updatedEvent = JSON.parse(JSON.stringify(event));
}
}
}
}
});
return updatedEvent;
},
removeAction: (productUuid, actionUuid) => {
let updatedEvent: EventsSchema | undefined;
set((state) => {
const product = state.products.find(p => p.productUuid === productUuid);
if (product) {
for (const event of product.eventDatas) {
if ('points' in event) {
// Handle ConveyorEventSchema
for (const point of (event as ConveyorEventSchema).points) {
}
} else if ('point' in event) {
const point = (event as any).point;
if (event.type === "roboticArm") {
if ('actions' in point) {
const index = point.actions.findIndex((a: any) => a.actionUuid === actionUuid);
if (index !== -1) {
point.actions.splice(index, 1);
updatedEvent = JSON.parse(JSON.stringify(event));
return;
}
}
} else if ('action' in point && point.action?.actionUuid === actionUuid) {
point.action = undefined;
updatedEvent = JSON.parse(JSON.stringify(event));
return;
}
}
}
}
});
return updatedEvent;
},
updateAction: (productUuid, actionUuid, updates) => {
let updatedEvent: EventsSchema | undefined;
set((state) => {
const product = state.products.find(p => p.productUuid === productUuid);
if (product) {
for (const event of product.eventDatas) {
if ('points' in event) {
for (const point of (event as ConveyorEventSchema).points) {
if (point.action && point.action.actionUuid === actionUuid) {
Object.assign(point.action, updates);
updatedEvent = JSON.parse(JSON.stringify(event));
return;
}
}
} else if ('point' in event) {
const point = (event as any).point;
if ('action' in point && point.action.actionUuid === actionUuid) {
Object.assign(point.action, updates);
updatedEvent = JSON.parse(JSON.stringify(event));
return;
} else if ('actions' in point) {
const action = point.actions.find((a: any) => a.actionUuid === actionUuid);
if (action) {
Object.assign(action, updates);
updatedEvent = JSON.parse(JSON.stringify(event));
return;
}
}
}
}
}
});
return updatedEvent;
},
// Trigger-level actions
addTrigger: (productUuid, actionUuid, trigger) => {
let updatedEvent: EventsSchema | undefined;
set((state) => {
const product = state.products.find(p => p.productUuid === productUuid);
if (product) {
for (const event of product.eventDatas) {
if ('points' in event) {
for (const point of (event as ConveyorEventSchema).points) {
if (point.action && point.action.actionUuid === actionUuid) {
const existingTrigger = point.action.triggers.find(t => t.triggerUuid === trigger.triggerUuid);
if (!existingTrigger) {
point.action.triggers.push(trigger);
updatedEvent = JSON.parse(JSON.stringify(event));
}
return;
}
}
} else if ('point' in event) {
const point = (event as any).point;
if ('action' in point && point.action.actionUuid === actionUuid) {
const existingTrigger = point.action.triggers.find((t: any) => t.triggerUuid === trigger.triggerUuid);
if (!existingTrigger) {
point.action.triggers.push(trigger);
updatedEvent = JSON.parse(JSON.stringify(event));
}
return;
} else if ('actions' in point) {
const action = point.actions.find((a: any) => a.actionUuid === actionUuid);
if (action) {
const existingTrigger = action.triggers.find((t: any) => t.triggerUuid === trigger.triggerUuid);
if (!existingTrigger) {
action.triggers.push(trigger);
updatedEvent = JSON.parse(JSON.stringify(event));
}
return;
}
}
}
}
}
});
return updatedEvent;
},
removeTrigger: (productUuid, triggerUuid) => {
let updatedEvent: EventsSchema | undefined;
set((state) => {
const product = state.products.find(p => p.productUuid === productUuid);
if (product) {
for (const event of product.eventDatas) {
if ('points' in event) {
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) {
point.action.triggers = point.action.triggers.filter(t => t.triggerUuid !== triggerUuid);
updatedEvent = JSON.parse(JSON.stringify(event));
}
}
}
} else if ('point' in event) {
const point = (event as any).point;
if ('action' in point && 'triggers' in point.action) {
const Trigger = point.action.triggers.find((t: any) => t.triggerUuid === triggerUuid);
if (Trigger) {
point.action.triggers = point.action.triggers.filter((t: any) => t.triggerUuid !== triggerUuid);
updatedEvent = JSON.parse(JSON.stringify(event));
}
} else if ('actions' in point) {
for (const action of point.actions) {
if ('triggers' in action) {
const Trigger = action.triggers.find((t: any) => t.triggerUuid === triggerUuid);
if (Trigger) {
action.triggers = action.triggers.filter((t: any) => t.triggerUuid !== triggerUuid);
updatedEvent = JSON.parse(JSON.stringify(event));
}
}
}
}
}
}
}
});
return updatedEvent;
},
updateTrigger: (productUuid, triggerUuid, updates) => {
let updatedEvent: EventsSchema | undefined;
set((state) => {
const product = state.products.find(p => p.productUuid === productUuid);
if (product) {
for (const event of product.eventDatas) {
if ('points' in event) {
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) {
Object.assign(trigger, updates);
updatedEvent = JSON.parse(JSON.stringify(event));
return;
}
}
}
} else if ('point' in event) {
const point = (event as any).point;
if ('action' in point && 'triggers' in point.action) {
const trigger = point.action.triggers.find((t: any) => t.triggerUuid === triggerUuid);
if (trigger) {
Object.assign(trigger, updates);
updatedEvent = JSON.parse(JSON.stringify(event));
return;
}
} else if ('actions' in point) {
for (const action of point.actions) {
if ('triggers' in action) {
const trigger = action.triggers.find((t: any) => t.triggerUuid === triggerUuid);
if (trigger) {
Object.assign(trigger, updates);
updatedEvent = JSON.parse(JSON.stringify(event));
return;
}
}
}
}
}
}
}
});
return updatedEvent;
},
// Renaming functions
renameProduct: (productUuid, newName) => {
set((state) => {
const product = state.products.find(p => p.productUuid === productUuid);
if (product) {
product.productName = newName;
}
});
},
renameAction: (productUuid, actionUuid, newName) => {
let updatedEvent: EventsSchema | undefined;
set((state) => {
const product = state.products.find(p => p.productUuid === productUuid);
if (product) {
for (const event of product.eventDatas) {
if ('points' in event) {
for (const point of (event as ConveyorEventSchema).points) {
if (point.action && point.action.actionUuid === actionUuid) {
point.action.actionName = newName;
updatedEvent = JSON.parse(JSON.stringify(event));
return;
}
}
} else if ('point' in event) {
const point = (event as any).point;
if ('action' in point && point.action.actionUuid === actionUuid) {
point.action.actionName = newName;
updatedEvent = JSON.parse(JSON.stringify(event));
return;
} else if ('actions' in point) {
const action = point.actions.find((a: any) => a.actionUuid === actionUuid);
if (action) {
action.actionName = newName;
updatedEvent = JSON.parse(JSON.stringify(event));
return;
}
}
}
}
}
});
return updatedEvent;
},
renameTrigger: (productUuid, triggerUuid, newName) => {
let updatedEvent: EventsSchema | undefined;
set((state) => {
const product = state.products.find(p => p.productUuid === productUuid);
if (product) {
for (const event of product.eventDatas) {
if ('points' in event) {
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) {
trigger.triggerName = newName;
updatedEvent = JSON.parse(JSON.stringify(event));
return;
}
}
}
} else if ('point' in event) {
const point = (event as any).point;
if ('action' in point && 'triggers' in point.action) {
const trigger = point.action.triggers.find((t: any) => t.triggerUuid === triggerUuid);
if (trigger) {
trigger.triggerName = newName;
updatedEvent = JSON.parse(JSON.stringify(event));
return;
}
} else if ('actions' in point) {
for (const action of point.actions) {
if ('triggers' in action) {
const trigger = action.triggers.find((t: any) => t.triggerUuid === triggerUuid);
if (trigger) {
trigger.triggerName = newName;
updatedEvent = JSON.parse(JSON.stringify(event));
return;
}
}
}
}
}
}
}
});
return updatedEvent;
},
// Helper functions
getProductById: (productUuid) => {
return get().products.find(p => p.productUuid === productUuid);
},
getEventByModelUuid: (productUuid, modelUuid) => {
const product = get().getProductById(productUuid);
if (!product) return undefined;
return product.eventDatas.find(e => 'modelUuid' in e && e.modelUuid === modelUuid);
},
getEventByActionUuid: (productUuid, actionUuid) => {
const product = get().getProductById(productUuid);
if (!product) return undefined;
for (const event of product.eventDatas) {
if ('points' in event) {
for (const point of (event as ConveyorEventSchema).points) {
if (point.action?.actionUuid === actionUuid) {
return event;
}
}
} else if ('point' in event) {
const point = (event as any).point;
if ('action' in point && point.action?.actionUuid === actionUuid) {
return event;
} else if ('actions' in point) {
const action = point.actions.find((a: any) => a.actionUuid === actionUuid);
if (action) {
return event;
}
}
}
}
return undefined;
},
getEventByTriggerUuid: (productUuid, triggerUuid) => {
const product = get().getProductById(productUuid);
if (!product) return undefined;
for (const event of product.eventDatas) {
if ('points' in event) {
for (const point of (event as ConveyorEventSchema).points) {
if (point.action?.triggers?.some(t => t.triggerUuid === triggerUuid)) {
return event;
}
}
} else if ('point' in event) {
const point = (event as any).point;
if ('action' in point) {
if (point.action?.triggers?.some((t: any) => t.triggerUuid === triggerUuid)) {
return event;
}
} else if ('actions' in point) {
for (const action of point.actions) {
if (action.triggers?.some((t: any) => t.triggerUuid === triggerUuid)) {
return event;
}
}
}
}
}
return undefined;
},
getEventByPointUuid: (productUuid, pointUuid) => {
const product = get().getProductById(productUuid);
if (!product) return undefined;
for (const event of product.eventDatas) {
if ('points' in event) {
if ((event as ConveyorEventSchema).points.some(p => p.uuid === pointUuid)) {
return event;
}
} else if ('point' in event) {
if ((event as any).point?.uuid === pointUuid) {
return event;
}
}
}
return undefined;
},
getPointByUuid: (productUuid, modelUuid, pointUuid) => {
const event = get().getEventByModelUuid(productUuid, modelUuid);
if (!event) return undefined;
if ('points' in event) {
return (event as ConveyorEventSchema).points.find(p => p.uuid === pointUuid);
} else if ('point' in event && (event as any).point.uuid === pointUuid) {
return (event as VehicleEventSchema | RoboticArmEventSchema | MachineEventSchema | StorageEventSchema).point;
}
return undefined;
},
getActionByUuid: (productUuid, actionUuid) => {
const product = get().products.find(p => p.productUuid === productUuid);
if (!product) return undefined;
for (const event of product.eventDatas) {
if ('points' in event) {
for (const point of (event as ConveyorEventSchema).points) {
if (point.action?.actionUuid === actionUuid) {
return point.action;
}
}
} else if ('point' in event) {
const point = (event as any).point;
if ('action' in point && point.action?.actionUuid === actionUuid) {
return point.action;
} else if ('actions' in point) {
const action = point.actions.find((a: any) => a.actionUuid === actionUuid);
if (action) return action;
}
}
}
return undefined;
},
getActionByPointUuid: (productUuid, pointUuid) => {
const product = get().products.find(p => p.productUuid === productUuid);
if (!product) return undefined;
for (const event of product.eventDatas) {
if ('points' in event) {
for (const point of (event as ConveyorEventSchema).points) {
if (point.uuid === pointUuid) {
return point.action;
}
}
} else if ('point' in event) {
const point = (event as any).point;
if (point.uuid === pointUuid) {
return point.action;
}
}
}
return undefined;
},
getModelUuidByPointUuid: (productUuid, pointUuid) => {
const product = get().products.find(p => p.productUuid === productUuid);
if (!product) return undefined;
for (const event of product.eventDatas) {
if ('points' in event) {
for (const point of (event as ConveyorEventSchema).points) {
if (point.uuid === pointUuid) {
return event.modelUuid;
}
}
} else if ('point' in event) {
const point = (event as any).point;
if (point.uuid === pointUuid) {
return event.modelUuid;
}
}
}
return undefined;
},
getModelUuidByActionUuid: (productUuid, actionUuid) => {
const product = get().products.find(p => p.productUuid === productUuid);
if (!product) return undefined;
for (const event of product.eventDatas) {
if ('points' in event) {
for (const point of (event as ConveyorEventSchema).points) {
if (point.action?.actionUuid === actionUuid) {
return event.modelUuid;
}
}
} else if ('point' in event) {
const point = (event as any).point;
if ('action' in point && point.action?.actionUuid === actionUuid) {
return event.modelUuid;
} else if ('actions' in point) {
const action = point.actions.find((a: any) => a.actionUuid === actionUuid);
if (action) return event.modelUuid;
}
}
}
return undefined;
},
getPointUuidByActionUuid: (productUuid, actionUuid) => {
const product = get().products.find(p => p.productUuid === productUuid);
if (!product) return undefined;
for (const event of product.eventDatas) {
if ('points' in event) {
for (const point of (event as ConveyorEventSchema).points) {
if (point.action?.actionUuid === actionUuid) {
return point.uuid;
}
}
} else if ('point' in event) {
const point = (event as any).point;
if ('action' in point && point.action?.actionUuid === actionUuid) {
return point.uuid;
} else if ('actions' in point) {
const action = point.actions.find((a: any) => a.actionUuid === actionUuid);
if (action) return point.uuid;
}
}
}
return undefined;
},
getTriggerByUuid: (productUuid, triggerUuid) => {
const product = get().products.find(p => p.productUuid === productUuid);
if (!product) return undefined;
for (const event of product.eventDatas) {
if ('points' in event) {
for (const point of (event as ConveyorEventSchema).points) {
for (const trigger of point.action?.triggers || []) {
if (trigger.triggerUuid === triggerUuid) {
return trigger;
}
}
}
} else if ('point' in event) {
const point = (event as any).point;
if ('action' in point) {
for (const trigger of point.action?.triggers || []) {
if (trigger.triggerUuid === triggerUuid) {
return trigger;
}
}
} else if ('actions' in point) {
for (const action of point.actions) {
for (const trigger of action.triggers || []) {
if (trigger.triggerUuid === triggerUuid) {
return trigger;
}
}
}
}
}
}
return undefined;
},
getIsEventInProduct: (productUuid, modelUuid) => {
const product = get().getProductById(productUuid);
if (!product) return false;
return product.eventDatas.some(e => 'modelUuid' in e && e.modelUuid === modelUuid);
}
}))
);

View File

@@ -0,0 +1,197 @@
import { create } from 'zustand';
import { immer } from 'zustand/middleware/immer';
import * as THREE from 'three';
interface SelectedEventSphereState {
selectedEventSphere: THREE.Mesh | null;
setSelectedEventSphere: (mesh: THREE.Mesh | null) => void;
clearSelectedEventSphere: () => void;
}
export const useSelectedEventSphere = create<SelectedEventSphereState>()(
immer((set) => ({
selectedEventSphere: null,
setSelectedEventSphere: (mesh) => {
set((state) => {
state.selectedEventSphere = mesh;
});
},
clearSelectedEventSphere: () => {
set((state) => {
state.selectedEventSphere = null;
});
},
}))
);
interface SelectedEventDataState {
selectedEventData: { data: EventsSchema; selectedPoint: string } | undefined;
setSelectedEventData: (data: EventsSchema, selectedPoint: string) => void;
clearSelectedEventData: () => void;
}
export const useSelectedEventData = create<SelectedEventDataState>()(
immer((set) => ({
selectedEventData: undefined,
setSelectedEventData: (data, selectedPoint) => {
set((state) => {
state.selectedEventData = { data, selectedPoint };
});
},
clearSelectedEventData: () => {
set((state) => {
state.selectedEventData = undefined;
});
},
}))
);
interface SelectedAssetState {
selectedAsset: EventsSchema | undefined;
setSelectedAsset: (EventData: EventsSchema) => void;
clearSelectedAsset: () => void;
}
export const useSelectedAsset = create<SelectedAssetState>()(
immer((set) => ({
selectedAsset: undefined,
setSelectedAsset: (EventData) => {
set((state) => {
state.selectedAsset = EventData;
});
},
clearSelectedAsset: () => {
set((state) => {
state.selectedAsset = undefined;
});
},
}))
);
interface SelectedProductState {
selectedProduct: { productUuid: string; productName: string };
setSelectedProduct: (productUuid: string, productName: string) => void;
clearSelectedProduct: () => void;
}
export const createSelectedProductStore = () => {
return create<SelectedProductState>()(
immer((set) => ({
selectedProduct: { productUuid: '', productName: '' },
setSelectedProduct: (productUuid, productName) => {
set((state) => {
state.selectedProduct.productUuid = productUuid;
state.selectedProduct.productName = productName;
});
},
clearSelectedProduct: () => {
set((state) => {
state.selectedProduct.productUuid = '';
state.selectedProduct.productName = '';
});
},
}))
)
}
export type SelectedProductType = ReturnType<typeof createSelectedProductStore>;
interface SelectedActionState {
selectedAction: { actionId: string | null; actionName: string | null };
setSelectedAction: (actionId: string, actionName: string) => void;
clearSelectedAction: () => void;
}
export const useSelectedAction = create<SelectedActionState>()(
immer((set) => ({
selectedAction: { actionId: null, actionName: null },
setSelectedAction: (actionId, actionName) => {
set((state) => {
state.selectedAction.actionId = actionId;
state.selectedAction.actionName = actionName;
});
},
clearSelectedAction: () => {
set((state) => {
state.selectedAction.actionId = null;
state.selectedAction.actionName = null;
});
},
}))
);
interface IsDraggingState {
isDragging: "start" | "end" | null;
setIsDragging: (state: "start" | "end" | null) => void;
}
export const useIsDragging = create<IsDraggingState>()(
immer((set) => ({
isDragging: null,
setIsDragging: (state) => {
set((s) => {
s.isDragging = state;
});
},
}))
);
interface IsRotatingState {
isRotating: "start" | "end" | null;
setIsRotating: (state: "start" | "end" | null) => void;
}
export const useIsRotating = create<IsRotatingState>()(
immer((set) => ({
isRotating: null,
setIsRotating: (state) => {
set((s) => {
s.isRotating = state;
});
},
}))
);
interface MainProductState {
mainProduct: { productUuid: string; productName: string } | null;
setMainProduct: (productUuid: string, productName: string) => void;
clearMainProduct: () => void;
}
export const useMainProduct = create<MainProductState>()(
immer((set) => ({
mainProduct: null,
setMainProduct: (productUuid: string, productName: string) => {
set((state) => {
state.mainProduct = { productUuid, productName };
});
},
clearMainProduct: () => {
set((state) => {
state.mainProduct = null;
});
},
}))
);
interface ComparisonProductState {
comparisonProduct: { productUuid: string; productName: string } | null;
setComparisonProduct: (productUuid: string, productName: string) => void;
clearComparisonProduct: () => void;
}
export const useComparisonProduct = create<ComparisonProductState>()(
immer((set) => ({
comparisonProduct: null,
setComparisonProduct: (productUuid: string, productName: string) => {
set((state) => {
state.comparisonProduct = { productUuid, productName };
});
},
clearComparisonProduct: () => {
set((state) => {
state.comparisonProduct = null;
});
},
}))
);

View File

@@ -0,0 +1,219 @@
import { create } from 'zustand';
import { immer } from 'zustand/middleware/immer';
interface StorageUnitStore {
storageUnits: StorageUnitStatus[];
addStorageUnit: (productUuid: string, storageUnit: StorageEventSchema) => void;
removeStorageUnit: (modelUuid: string) => void;
updateStorageUnit: (
modelUuid: string,
updates: Partial<Omit<StorageUnitStatus, 'modelUuid' | 'productUuid'>>
) => void;
clearStorageUnits: () => void;
setStorageUnitActive: (modelUuid: string, isActive: boolean) => void;
setStorageUnitState: (modelUuid: string, newState: StorageUnitStatus['state']) => void;
updateCurrentLoad: (modelUuid: string, incrementBy: number) => void;
incrementActiveTime: (modelUuid: string, incrementBy: number) => void;
incrementIdleTime: (modelUuid: string, incrementBy: number) => void;
addCurrentMaterial: (modelUuid: string, materialType: string, materialId: string) => void;
setCurrentMaterials: (modelUuid: string, materials: { materialType: string; materialId: string; }[]) => void;
getLastMaterial: (modelUuid: string) => { materialId: string; materialType: string; } | undefined;
removeLastMaterial: (modelUuid: string) => { materialId: string; materialType: string; } | undefined;
clearCurrentMaterials: (modelUuid: string) => void;
getStorageUnitById: (modelUuid: string) => StorageUnitStatus | undefined;
getStorageUnitsByProduct: (productUuid: string) => StorageUnitStatus[];
getStorageUnitsBystate: (state: string) => StorageUnitStatus[];
getActiveStorageUnits: () => StorageUnitStatus[];
getIdleStorageUnits: () => StorageUnitStatus[];
getFullStorageUnits: () => StorageUnitStatus[];
getEmptyStorageUnits: () => StorageUnitStatus[];
}
export const createStorageUnitStore = () => {
return create<StorageUnitStore>()(
immer((set, get) => ({
storageUnits: [],
addStorageUnit: (productUuid, storageUnit) => {
set((state) => {
const exists = state.storageUnits.some(s => s.modelUuid === storageUnit.modelUuid);
if (!exists) {
state.storageUnits.push({
...storageUnit,
productUuid,
isActive: false,
idleTime: 0,
activeTime: 0,
currentLoad: 0,
currentMaterials: [],
state: 'idle'
});
}
});
},
removeStorageUnit: (modelUuid) => {
set((state) => {
state.storageUnits = state.storageUnits.filter(s => s.modelUuid !== modelUuid);
});
},
updateStorageUnit: (modelUuid, updates) => {
set((state) => {
const unit = state.storageUnits.find(s => s.modelUuid === modelUuid);
if (unit) {
Object.assign(unit, updates);
}
});
},
clearStorageUnits: () => {
set(() => ({
storageUnits: [],
}));
},
setStorageUnitActive: (modelUuid, isActive) => {
set((state) => {
const unit = state.storageUnits.find(s => s.modelUuid === modelUuid);
if (unit) {
unit.isActive = isActive;
}
});
},
setStorageUnitState: (modelUuid, newState) => {
set((state) => {
const unit = state.storageUnits.find(s => s.modelUuid === modelUuid);
if (unit) {
unit.state = newState;
}
});
},
updateCurrentLoad: (modelUuid, incrementBy) => {
set((state) => {
const unit = state.storageUnits.find(s => s.modelUuid === modelUuid);
if (unit) {
unit.currentLoad += incrementBy;
}
});
},
incrementActiveTime: (modelUuid, incrementBy) => {
set((state) => {
const unit = state.storageUnits.find(s => s.modelUuid === modelUuid);
if (unit) {
unit.activeTime += incrementBy;
}
});
},
incrementIdleTime: (modelUuid, incrementBy) => {
set((state) => {
const unit = state.storageUnits.find(s => s.modelUuid === modelUuid);
if (unit) {
unit.idleTime += incrementBy;
}
});
},
addCurrentMaterial: (modelUuid, materialType, materialId) => {
set((state) => {
const storage = state.storageUnits.find((s) => s.modelUuid === modelUuid);
if (storage) {
storage.currentMaterials.push({ materialType, materialId });
}
});
},
setCurrentMaterials: (modelUuid, materials) => {
set((state) => {
const storage = state.storageUnits.find((s) => s.modelUuid === modelUuid);
if (storage) {
storage.currentMaterials = materials;
}
});
},
getLastMaterial: (modelUuid) => {
let removedMaterial: { materialId: string; materialType: string; } | undefined;
set((state) => {
const storage = state.storageUnits.find((s) => s.modelUuid === modelUuid);
if (storage) {
if (storage.currentMaterials.length > 0) {
const material = storage.currentMaterials[storage.currentMaterials.length - 1];
if (material) {
removedMaterial = { materialId: material.materialId, materialType: material.materialType };
}
}
}
});
return removedMaterial;
},
removeLastMaterial: (modelUuid) => {
let removedMaterial: { materialId: string; materialType: string; } | undefined;
set((state) => {
const storage = state.storageUnits.find((s) => s.modelUuid === modelUuid);
if (storage) {
if (storage.currentMaterials.length > 0) {
const material = storage.currentMaterials.pop();
if (material) {
removedMaterial = { materialId: material.materialId, materialType: material.materialType };
}
}
}
});
return removedMaterial;
},
clearCurrentMaterials: (modelUuid) => {
set((state) => {
const storage = state.storageUnits.find((s) => s.modelUuid === modelUuid);
if (storage) {
storage.currentMaterials = [];
}
});
},
getStorageUnitById: (modelUuid) => {
return get().storageUnits.find(s => s.modelUuid === modelUuid);
},
getStorageUnitsByProduct: (productUuid) => {
return get().storageUnits.filter(s => s.productUuid === productUuid);
},
getStorageUnitsBystate: (state) => {
return get().storageUnits.filter(s => s.state === state);
},
getActiveStorageUnits: () => {
return get().storageUnits.filter(s => s.isActive);
},
getIdleStorageUnits: () => {
return get().storageUnits.filter(s => !s.isActive && s.state === 'idle');
},
getFullStorageUnits: () => {
return get().storageUnits.filter(
s => s.currentLoad >= s.point.action.storageCapacity
);
},
getEmptyStorageUnits: () => {
return get().storageUnits.filter(s => s.currentLoad === 0);
},
}))
)
}
export type StorageUnitStoreType = ReturnType<typeof createStorageUnitStore>;

View File

@@ -0,0 +1,257 @@
import { create } from "zustand";
import { immer } from "zustand/middleware/immer";
interface VehiclesStore {
vehicles: VehicleStatus[];
addVehicle: (productUuid: string, event: VehicleEventSchema) => void;
removeVehicle: (modelUuid: string) => void;
updateVehicle: (
modelUuid: string,
updates: Partial<Omit<VehicleStatus, "modelUuid" | "productUuid">>
) => void;
clearvehicles: () => void;
setVehicleActive: (modelUuid: string, isActive: boolean) => void;
setVehiclePicking: (modelUuid: string, isPicking: boolean) => void;
updateSteeringAngle: (modelUuid: string, steeringAngle: number) => void;
incrementVehicleLoad: (modelUuid: string, incrementBy: number) => void;
decrementVehicleLoad: (modelUuid: string, decrementBy: number) => void;
setVehicleLoad: (modelUuid: string, load: number) => void;
setVehicleState: (
modelUuid: string,
newState: VehicleStatus["state"]
) => void;
addCurrentMaterial: (modelUuid: string, materialType: string, materialId: string) => void;
setCurrentMaterials: (modelUuid: string, materials: { materialType: string; materialId: string; }[]) => void;
removeLastMaterial: (modelUuid: string) => { materialId: string; materialType: string; } | undefined;
getLastMaterial: (modelUuid: string) => { materialId: string; materialType: string; } | undefined;
clearCurrentMaterials: (modelUuid: string) => void;
incrementActiveTime: (modelUuid: string, incrementBy: number) => void;
incrementIdleTime: (modelUuid: string, incrementBy: number) => void;
resetTime: (modelUuid: string) => void;
getVehicleById: (modelUuid: string) => VehicleStatus | undefined;
getVehiclesByProduct: (productUuid: string) => VehicleStatus[];
getVehiclesByState: (state: string) => VehicleStatus[];
getActiveVehicles: () => VehicleStatus[];
}
export const createVehicleStore = () => {
return create<VehiclesStore>()(
immer((set, get) => ({
vehicles: [],
addVehicle: (productUuid, event) => {
set((state) => {
const exists = state.vehicles.some((v) => v.modelUuid === event.modelUuid);
if (!exists) {
state.vehicles.push({
...event,
productUuid,
isActive: false,
isPicking: false,
idleTime: 0,
activeTime: 0,
currentLoad: 0,
currentMaterials: [],
distanceTraveled: 0,
state: 'idle'
});
}
});
},
removeVehicle: (modelUuid) => {
set((state) => {
state.vehicles = state.vehicles.filter(
(v) => v.modelUuid !== modelUuid
);
});
},
updateVehicle: (modelUuid, updates) => {
set((state) => {
const vehicle = state.vehicles.find((v) => v.modelUuid === modelUuid);
if (vehicle) {
Object.assign(vehicle, updates);
}
});
},
clearvehicles: () => {
set((state) => {
state.vehicles = [];
});
},
setVehicleActive: (modelUuid, isActive) => {
set((state) => {
const vehicle = state.vehicles.find((v) => v.modelUuid === modelUuid);
if (vehicle) {
vehicle.isActive = isActive;
}
});
},
setVehiclePicking: (modelUuid, isPicking) => {
set((state) => {
const vehicle = state.vehicles.find((v) => v.modelUuid === modelUuid);
if (vehicle) {
vehicle.isPicking = isPicking;
}
});
},
updateSteeringAngle: (modelUuid, steeringAngle) => {
set((state) => {
const vehicle = state.vehicles.find((v) => v.modelUuid === modelUuid);
if (vehicle) {
vehicle.point.action.steeringAngle = steeringAngle;
}
});
},
incrementVehicleLoad: (modelUuid, incrementBy) => {
set((state) => {
const vehicle = state.vehicles.find((v) => v.modelUuid === modelUuid);
if (vehicle) {
vehicle.currentLoad += incrementBy;
}
});
},
decrementVehicleLoad: (modelUuid, decrementBy) => {
set((state) => {
const vehicle = state.vehicles.find((v) => v.modelUuid === modelUuid);
if (vehicle) {
vehicle.currentLoad -= decrementBy;
}
});
},
setVehicleLoad: (modelUuid, load) => {
set((state) => {
const vehicle = state.vehicles.find((v) => v.modelUuid === modelUuid);
if (vehicle) {
vehicle.currentLoad = load;
}
});
},
setVehicleState: (modelUuid, newState) => {
set((state) => {
const vehicle = state.vehicles.find((v) => v.modelUuid === modelUuid);
if (vehicle) {
vehicle.state = newState;
}
});
},
addCurrentMaterial: (modelUuid, materialType, materialId) => {
set((state) => {
const vehicle = state.vehicles.find((v) => v.modelUuid === modelUuid);
if (vehicle) {
vehicle.currentMaterials.push({ materialType, materialId });
}
});
},
setCurrentMaterials: (modelUuid, materials) => {
set((state) => {
const vehicle = state.vehicles.find((v) => v.modelUuid === modelUuid);
if (vehicle) {
vehicle.currentMaterials = materials;
}
});
},
removeLastMaterial: (modelUuid) => {
let removedMaterial: { materialId: string; materialType: string; } | undefined;
set((state) => {
const vehicle = state.vehicles.find((v) => v.modelUuid === modelUuid);
if (vehicle) {
if (vehicle.currentMaterials.length > 0) {
const material = vehicle.currentMaterials.pop();
if (material) {
removedMaterial = { materialId: material.materialId, materialType: material.materialType };
}
}
}
});
return removedMaterial;
},
getLastMaterial: (modelUuid) => {
let removedMaterial: { materialId: string; materialType: string; } | undefined;
set((state) => {
const vehicle = state.vehicles.find((v) => v.modelUuid === modelUuid);
if (vehicle) {
if (vehicle.currentMaterials.length > 0) {
removedMaterial = {
materialId: vehicle.currentMaterials[vehicle.currentMaterials.length - 1].materialId,
materialType: vehicle.currentMaterials[vehicle.currentMaterials.length - 1].materialType
};
}
}
});
return removedMaterial;
},
clearCurrentMaterials: (modelUuid) => {
set((state) => {
const vehicle = state.vehicles.find((v) => v.modelUuid === modelUuid);
if (vehicle) {
vehicle.currentMaterials = [];
}
});
},
incrementActiveTime: (modelUuid, incrementBy) => {
set((state) => {
const vehicle = state.vehicles.find((v) => v.modelUuid === modelUuid);
if (vehicle) {
vehicle.activeTime += incrementBy;
}
});
},
incrementIdleTime: (modelUuid, incrementBy) => {
set((state) => {
const vehicle = state.vehicles.find((v) => v.modelUuid === modelUuid);
if (vehicle) {
vehicle.idleTime += incrementBy;
}
});
},
resetTime: (modelUuid) => {
set((state) => {
const vehicle = state.vehicles.find((v) => v.modelUuid === modelUuid);
if (vehicle) {
vehicle.activeTime = 0;
vehicle.idleTime = 0;
}
});
},
getVehicleById: (modelUuid) => {
return get().vehicles.find((v) => v.modelUuid === modelUuid);
},
getVehiclesByProduct: (productUuid) => {
return get().vehicles.filter((v) => v.productUuid === productUuid);
},
getVehiclesByState: (state) => {
return get().vehicles.filter((v) => v.state === state);
},
getActiveVehicles: () => {
return get().vehicles.filter((v) => v.isActive);
},
}))
)
}
export type VehicleStoreType = ReturnType<typeof createVehicleStore>;

View File

@@ -0,0 +1,42 @@
import { create } from "zustand";
interface ModuleStore {
activeModule: string;
setActiveModule: (module: string) => void;
}
const useModuleStore = create<ModuleStore>((set) => ({
activeModule: "builder", // Initial state
setActiveModule: (module) => set({ activeModule: module }), // Update state
}));
export default useModuleStore;
// New store for subModule
type SubModule = 'properties' | 'simulations' | 'mechanics' | 'analysis' | 'zoneProperties';
interface SubModuleStore {
subModule: SubModule;
setSubModule: (subModule: SubModule) => void;
}
const useSubModuleStore = create<SubModuleStore>((set) => ({
subModule: "properties", // Initial subModule state
setSubModule: (value) => set({ subModule: value }), // Update subModule state
}));
export { useSubModuleStore };
interface ThreeDState {
toggleThreeD: boolean;
setToggleThreeD: (value: boolean) => void;
}
// Create the Zustand store
const useThreeDStore = create<ThreeDState>((set) => ({
toggleThreeD: true, // Initial state
setToggleThreeD: (value) => set({ toggleThreeD: value }), // Action to update the state
}));
export { useThreeDStore };

View File

@@ -0,0 +1,49 @@
import { create } from "zustand";
type PlayButtonStore = {
isPlaying: boolean; // Updated state name to reflect the play/pause status more clearly
setIsPlaying: (value: boolean) => void; // Updated setter function name for clarity
};
type PauseButtonStore = {
isPaused: boolean; // Updated state name to reflect the play/pause status more clearly
setIsPaused: (value: boolean) => void; // Updated setter function name for clarity
};
type ResetButtonStore = {
isReset: boolean; // Updated state name to reflect the play/pause status more clearly
setReset: (value: boolean) => void; // Updated setter function name for clarity
};
interface AnimationSpeedState {
speed: number;
setSpeed: (value: number) => void;
}
export const usePlayButtonStore = create<PlayButtonStore>((set) => ({
isPlaying: false, // Default state for play/pause
setIsPlaying: (value) => set({ isPlaying: value }), // Update isPlaying state
}));
export const useResetButtonStore = create<ResetButtonStore>((set) => ({
isReset: false, // Default state for play/pause
setReset: (value) => set({ isReset: value }), // Update isPlaying state
}));
export const usePauseButtonStore = create<PauseButtonStore>((set) => ({
isPaused: false, // Default state for play/pause
setIsPaused: (value) => set({ isPaused: value }), // Update isPlaying state
}));
export const useAnimationPlaySpeed = create<AnimationSpeedState>((set) => ({
speed: 1,
setSpeed: (value) => set({ speed: value }),
}));
interface CameraModeState {
walkMode: boolean;
setWalkMode: (enabled: boolean) => void;
toggleWalkMode: () => void;
}
const useCameraModeStore = create<CameraModeState>((set) => ({
walkMode: false,
setWalkMode: (enabled) => set({ walkMode: enabled }),
toggleWalkMode: () => set((state) => ({ walkMode: !state.walkMode })),
}));
export default useCameraModeStore;

View File

@@ -0,0 +1,51 @@
import { create } from "zustand";
export interface Widget {
id: string;
type: string;
title: string;
panel: string;
data: any;
}
export interface Template {
id: string;
name: string;
panelOrder: string[];
widgets: Widget[];
floatingWidget: any[]; // Fixed empty array type
widgets3D: any[]; // Fixed empty array type
snapshot?: string | null;
}
interface TemplateStore {
templates: Template[];
addTemplate: (template: Template) => void;
setTemplates: (templates: Template[]) => void; // Changed from `setTemplate`
removeTemplate: (id: string) => void;
}
export const useTemplateStore = create<TemplateStore>((set) => ({
templates: [],
// Add a new template to the list
addTemplate: (template) =>
set((state) => ({
templates: [...state.templates, template],
})),
// Set (replace) the templates list with a new array
setTemplates: (templates) =>
set(() => ({
templates, // Ensures no duplication
})),
// Remove a template by ID
removeTemplate: (id) =>
set((state) => ({
templates: state.templates.filter((t) => t.id !== id),
})),
}));
export default useTemplateStore;

View File

@@ -0,0 +1,11 @@
import { create } from "zustand";
interface ThemeState {
themeColor: string[]; // This should be an array of strings
setThemeColor: (colors: string[]) => void; // This function will accept an array of strings
}
export const useThemeStore = create<ThemeState>((set) => ({
themeColor: ["#5c87df", "#EEEEFE", "#969BA7"],
setThemeColor: (colors) => set({ themeColor: colors }),
}));

View File

@@ -0,0 +1,26 @@
import { create } from "zustand";
interface ToggleState {
toggleUILeft: boolean;
toggleUIRight: boolean;
setToggleUI: (value1: boolean, value2: boolean) => void;
}
export const useToggleStore = create<ToggleState>((set) => ({
toggleUILeft: true,
toggleUIRight: false,
setToggleUI: (value1: boolean, value2: boolean) => {
set({ toggleUILeft: value1, toggleUIRight: value2 });
},
}));
interface PlayerState {
hidePlayer: boolean;
setHidePlayer: (hide: boolean) => void;
}
// Create the Zustand store
export const usePlayerStore = create<PlayerState>((set) => ({
hidePlayer: false, // initial state
setHidePlayer: (hide) => set({ hidePlayer: hide }), // state updater
}));

View File

@@ -0,0 +1,35 @@
import { create } from "zustand";
export interface Widget {
id: string;
type: string; // Can be chart type or "progress"
panel: "top" | "bottom" | "left" | "right";
title: string;
fontFamily?: string;
fontSize?: string;
fontWeight?: string;
data?: any;
Data?:any;
}
interface WidgetStore {
draggedAsset: Widget | null; // The currently dragged widget asset
widgets: Widget[]; // List of all widgets
selectedChartId: any;
setDraggedAsset: (asset: Widget | null) => void; // Setter for draggedAsset
addWidget: (widget: Widget) => void; // Add a new widget
setWidgets: (widgets: Widget[]) => void; // Replace the entire widgets array
setSelectedChartId: (widget: any | null) => void; // Set the selected chart/widget
}
// Create the store with Zustand
export const useWidgetStore = create<WidgetStore>((set) => ({
draggedAsset: null,
widgets: [],
selectedChartId: null, // Initialize as null, not as an array
setDraggedAsset: (asset) => set({ draggedAsset: asset }),
addWidget: (widget) =>
set((state) => ({ widgets: [...state.widgets, widget] })),
setWidgets: (widgets) => set({ widgets }),
setSelectedChartId: (widget) => set({ selectedChartId: widget }),
}));

View File

@@ -0,0 +1,53 @@
import { create } from "zustand";
interface Measurement {
name: string;
fields: string;
}
interface MeasurementStore {
measurements: Record<string, Measurement>; // Change array to Record<string, Measurement>
interval: number;
duration: string;
name: string;
header: string;
flotingDuration: string;
flotingMeasurements: Record<string, Measurement>; // Change array to Record<string, Measurement>
setMeasurements: (newMeasurements: Record<string, Measurement>) => void;
updateDuration: (newDuration: string) => void;
updateName: (newName: string) => void;
updateHeader: (newHeader: string) => void;
updateFlotingDuration: (newFlotingDuration: string) => void;
setFlotingMeasurements: (newFlotingMeasurements: Record<string, Measurement>) => void;
}
const useChartStore = create<MeasurementStore>((set) => ({
measurements: {}, // Initialize as an empty object
interval: 1000,
duration: "1h",
name:'',
header:'',
flotingDuration: "1h",
flotingMeasurements: {},
setMeasurements: (newMeasurements) =>
set(() => ({ measurements: newMeasurements })),
updateDuration: (newDuration) =>
set(() => ({ duration: newDuration })),
updateName: (newName) =>
set(() => ({ name: newName })),
updateHeader: (newHeader) =>
set(() => ({ header: newHeader })),
updateFlotingDuration: (newFlotingDuration) =>
set(() => ({ flotingDuration: newFlotingDuration })),
setFlotingMeasurements: (newFlotingMeasurements) =>
set(() => ({ flotingMeasurements: newFlotingMeasurements })),
}));
export default useChartStore;

View File

@@ -0,0 +1,200 @@
import { create } from "zustand";
import { useSocketStore } from "../builder/store";
import useChartStore from "./useChartStore";
type DroppedObject = {
className: string;
id: string;
position: {
top: number | "auto";
left: number | "auto";
right: number | "auto";
bottom: number | "auto";
};
value?: number;
per?: string;
header?: string;
Data: {};
};
type Zone = {
zoneName: string;
zoneUuid: string;
objects: DroppedObject[];
};
type DroppedObjectsState = {
zones: Record<string, Zone>;
setZone: (zoneName: string, zoneUuid: string) => void;
addObject: (zoneName: string, newObject: DroppedObject) => void;
updateObjectPosition: (
zoneName: string,
index: number,
newPosition: {
top: number | "auto";
left: number | "auto";
right: number | "auto";
bottom: number | "auto";
}
) => void;
deleteObject: (zoneName: string, id: string) => void; // Add this line
duplicateObject: (zoneName: string, index: number, projectId?: string) => void; // Add this line
};
export const useDroppedObjectsStore = create<DroppedObjectsState>((set) => ({
zones: {},
setZone: (zoneName: string, zoneUuid: string) =>
set((state) => ({
zones: {
[zoneName]: state.zones[zoneName] || { zoneName, zoneUuid, objects: [] }, // Keep existing zone if it exists
},
})),
addObject: (zoneName: string, newObject: DroppedObject) =>
set((state) => ({
zones: {
...state.zones,
[zoneName]: {
...state.zones[zoneName],
objects: [...state.zones[zoneName].objects, newObject], // Append new object
},
},
})),
updateObjectPosition: (zoneName, index, newPosition) =>
set((state) => {
const zone = state.zones[zoneName];
if (!zone) return state;
return {
zones: {
[zoneName]: {
...zone,
objects: zone.objects.map((obj, i) =>
i === index ? { ...obj, position: newPosition } : obj
),
},
},
};
}),
deleteObject: (zoneName: string, id: string) =>
set((state) => {
const zone = state.zones[zoneName];
if (!zone) return state;
return {
zones: {
[zoneName]: {
...zone,
objects: zone.objects.filter((obj) => obj.id !== id), // Remove object at the given index
},
},
};
}),
duplicateObject: async (zoneName: string, index: number, projectId?: string) => {
const state = useDroppedObjectsStore.getState(); // Get the current state
const zone = state.zones[zoneName];
let socketState = useSocketStore.getState();
let iotData = useChartStore.getState();
let visualizationSocket = socketState.visualizationSocket;
let iotMeasurements = iotData.flotingMeasurements;
let iotDuration = iotData.flotingDuration;
let iotHeader = iotData.header
if (!zone) return;
const originalObject = zone.objects[index];
if (!originalObject) return;
const email = localStorage.getItem("email") || "";
const organization = email?.split("@")[1]?.split(".")[0];
const userId = localStorage.getItem("userId");
// Create a shallow copy of the object with a unique ID and slightly adjusted position
const duplicatedObject: DroppedObject = {
...originalObject,
Data: {
measurements: iotMeasurements,
duration: iotDuration,
},
header: iotHeader,
id: `${originalObject.id}-copy-${Date.now()}`, // Unique ID
position: {
...originalObject.position,
top:
typeof originalObject.position.top === "number"
? originalObject.position.top + 20 // Offset vertically
: originalObject.position.top,
left:
typeof originalObject.position.left === "number"
? originalObject.position.left + 20 // Offset horizontally
: originalObject.position.left,
},
};
console.log("duplicated object", duplicatedObject);
let duplicateFloatingWidget = {
organization: organization,
widget: duplicatedObject,
zoneUuid: zone.zoneUuid,
index: index,
projectId, userId
};
if (visualizationSocket) {
visualizationSocket.emit(
"v1:viz-float:addDuplicate",
duplicateFloatingWidget
);
}
useDroppedObjectsStore.setState((state) => ({
zones: {
...state.zones,
[zoneName]: {
...state.zones[zoneName],
objects: [...state.zones[zoneName].objects, duplicatedObject], // Append duplicated object
},
},
}));
// Make async API call outside of Zustand set function
// let response = await addingFloatingWidgets(
// zone.zoneUuid,
// organization,
// duplicatedObject
// );
// if (response.message === "FloatWidget created successfully") {
// Update the state inside `set`
// }
},
}));
export interface DroppedObjects {
header: string;
id: string;
Data: {};
value: string | number; // ✅ Allows both numbers and formatted strings
per: string;
className: string;
position: { top: number; left: number; right: number; bottom: number }; // ✅ Ensures position is a tuple
}
export interface Zones {
zoneName: string;
zoneUuid: string;
objects: DroppedObject[];
}
export const use3DWidget = create<any>((set: any) => ({
widgets3D: [],
setWidgets3D: (x: any) => set({ widgets3D: x }),
}));
export const useFloatingWidget = create<any>((set: any) => ({
floatingWidget: [],
setFloatingWidget: (x: any) => set({ floatingWidget: x }),
}));

View File

@@ -0,0 +1,122 @@
import { create } from "zustand";
type WidgetData = {
id: string;
type: string;
position: [number, number, number];
rotation?: [number, number, number];
tempPosition?: [number, number, number];
};
type ZoneWidgetStore = {
zoneWidgetData: Record<string, WidgetData[]>;
setZoneWidgetData: (zoneUuid: string, widgets: WidgetData[]) => void;
addWidget: (zoneUuid: string, widget: WidgetData) => void;
tempWidget: (zoneUuid: string, widget: WidgetData) => void;
updateWidgetPosition: (zoneUuid: string, widgetId: string, newPosition: [number, number, number]) => void;
tempWidgetPosition: (zoneUuid: string, widgetId: string, newPosition: [number, number, number]) => void;
updateWidgetRotation: (zoneUuid: string, widgetId: string, newRotation: [number, number, number]) => void;
};
export const useZoneWidgetStore = create<ZoneWidgetStore>((set) => ({
zoneWidgetData: {},
setZoneWidgetData: (zoneUuid: string, widgets: WidgetData[]) =>
set((state: ZoneWidgetStore) => ({
zoneWidgetData: { ...state.zoneWidgetData, [zoneUuid]: widgets },
})),
addWidget: (zoneUuid: string, widget: WidgetData) =>
set((state: ZoneWidgetStore) => ({
zoneWidgetData: {
...state.zoneWidgetData,
[zoneUuid]: [...(state.zoneWidgetData[zoneUuid] || []), { ...widget, rotation: widget.rotation || [0, 0, 0] }],
},
})),
tempWidget: (zoneUuid: string, widget: WidgetData) =>
set((state: ZoneWidgetStore) => ({
zoneWidgetData: {
...state.zoneWidgetData,
[zoneUuid]: [...(state.zoneWidgetData[zoneUuid] || []), { ...widget, rotation: widget.rotation || [0, 0, 0] }],
},
})),
updateWidgetPosition: (zoneUuid: string, widgetId: string, newPosition: [number, number, number]) =>
set((state: ZoneWidgetStore) => {
const widgets = state.zoneWidgetData[zoneUuid] || [];
return {
zoneWidgetData: {
...state.zoneWidgetData,
[zoneUuid]: widgets.map((widget: WidgetData) =>
widget.id === widgetId ? { ...widget, position: newPosition } : widget
),
},
};
}),
tempWidgetPosition: (zoneUuid: string, widgetId: string, newPosition: [number, number, number]) =>
set((state: ZoneWidgetStore) => {
const widgets = state.zoneWidgetData[zoneUuid] || [];
return {
zoneWidgetData: {
...state.zoneWidgetData,
[zoneUuid]: widgets.map((widget: WidgetData) =>
widget.id === widgetId ? { ...widget, position: newPosition } : widget
),
},
};
}),
updateWidgetRotation: (zoneUuid: string, widgetId: string, newRotation: [number, number, number]) =>
set((state: ZoneWidgetStore) => {
const widgets = state.zoneWidgetData[zoneUuid] || [];
return {
zoneWidgetData: {
...state.zoneWidgetData,
[zoneUuid]: widgets.map((widget: WidgetData) =>
widget.id === widgetId ? { ...widget, rotation: newRotation } : widget
),
},
};
}),
}));
interface RightClickStore {
rightClickSelected: string | null;
setRightClickSelected: (x: string | null) => void;
}
export const useRightClickSelected = create<RightClickStore>((set) => ({
rightClickSelected: null, // Default to null
setRightClickSelected: (x) => set({ rightClickSelected: x }),
}));
export const useTopData = create<any>((set: any) => ({
top: 0,
setTop: (x: any) => set({ top: x }),
}));
export const useLeftData = create<any>((set: any) => ({
left: 0,
setLeft: (x: any) => set({ left: x }),
}));
interface RightSelectStore {
rightSelect: string | null;
setRightSelect: (x: string | null) => void;
}
export const useRightSelected = create<RightSelectStore>((set) => ({
rightSelect: null, // Default state is null
setRightSelect: (x) => set({ rightSelect: x }),
}));
interface EditWidgetOptionsStore {
editWidgetOptions: boolean;
setEditWidgetOptions: (value: boolean) => void;
}
export const useEditWidgetOptionsStore = create<EditWidgetOptionsStore>((set) => ({
editWidgetOptions: false, // Initial state
setEditWidgetOptions: (value: boolean) => set({ editWidgetOptions: value }),
}));

View File

@@ -0,0 +1,68 @@
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[];
zoneUuid: string;
zoneViewPortTarget: number[];
zoneViewPortPosition: number[];
widgets: Widget[];
}
interface SelectedZoneStore {
selectedZone: SelectedZoneState;
setSelectedZone: (
zone:
| Partial<SelectedZoneState>
| ((prev: SelectedZoneState) => SelectedZoneState)
) => void;
clearSelectedZone: () => void;
}
export const useSelectedZoneStore = create<SelectedZoneStore>((set) => ({
selectedZone: {
zoneName: "",
activeSides: [],
panelOrder: [],
lockedPanels: [],
points: [],
zoneUuid: "",
zoneViewPortTarget: [],
zoneViewPortPosition: [],
widgets: [],
},
setSelectedZone: (zone) =>
set((state) => ({
selectedZone:
typeof zone === "function"
? zone(state.selectedZone)
: { ...state.selectedZone, ...zone },
})),
clearSelectedZone: () =>
set(() => ({
selectedZone: {
zoneName: "",
activeSides: [],
panelOrder: [],
lockedPanels: [],
points: [],
zoneUuid: "",
zoneViewPortTarget: [],
zoneViewPortPosition: [],
widgets: [],
},
})),
}));